Skip to content

Commit 2f9e55e

Browse files
author
Chris K
committed
Preserve expanded state while updating.
1 parent b3de9f8 commit 2f9e55e

File tree

4 files changed

+127
-30
lines changed

4 files changed

+127
-30
lines changed

src/ecma-debugger/evlistenertooltip/evlisteners.js

Lines changed: 95 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,8 @@ cls.EventName = function(name)
99
{
1010
this.name = name;
1111
this.model = null;
12-
this.rt_listeners = null,
13-
this.expanded = null;
12+
this.rt_listeners = null;
13+
this.is_expanded = false;
1414
this.rt_id = 0;
1515
this.obj_id = 0;
1616
};
@@ -22,6 +22,8 @@ cls.EvenetListeners = function(view)
2222
this.update = function() {};
2323
this.get_data = function() {};
2424
this.expand_listeners = function(rt_id, obj_id, ev_name, cb) {};
25+
this.collapse_listeners = function(rt_id, ev_name) {};
26+
this.is_expanded = function(rt_id, name) {};
2527

2628
var SUCCESS = 0;
2729
var SEARCH_TYPE_EVENT = 5;
@@ -38,7 +40,7 @@ cls.EvenetListeners = function(view)
3840
[
3941
{
4042
name: <name>,
41-
expanded: <boolean>,
43+
is_expanded: <boolean>,
4244
},
4345
...
4446
]
@@ -50,7 +52,8 @@ cls.EvenetListeners = function(view)
5052

5153
this._update_rt_list = function(rt_id_list)
5254
{
53-
var ctx = {rt_id_list: rt_id_list, rt_map: {}, win_id_map: {}};
55+
var ctx = {rt_id_list: rt_id_list, rt_map: {}, win_id_map: {}, expanded_map: {}};
56+
ctx.handle_expand_listener = this._handle_expand_listener_on_update.bind(this, ctx);
5457
rt_id_list.forEach(this._get_window_ids.bind(this, ctx));
5558
};
5659

@@ -87,47 +90,85 @@ cls.EvenetListeners = function(view)
8790

8891
this._get_event_names = function(ctx, rt_id)
8992
{
90-
var tag = this._tagman.set_callback(this, this._handle_get_event_names, [ctx, rt_id]);
93+
var tag = this._tagman.set_callback(this, this._handle_get_event_names, [ctx]);
9194
var msg = [rt_id];
9295
this._esdb.requestGetEventNames(tag, msg);
9396
};
9497

95-
this._handle_get_event_names = function(status, message, ctx, rt_id)
98+
this._handle_get_event_names = function(status, message, ctx)
9699
{
97100
if (status === SUCCESS)
98101
{
99102
var RUNTIME_ID = 0;
100103
var OBJECT_ID = 1;
101104
var EVENT_NAMES = 2;
102-
ctx.rt_map[message[RUNTIME_ID]] = null;
105+
var rt_id = message[RUNTIME_ID];
106+
var obj_id = message[OBJECT_ID];
107+
ctx.rt_map[rt_id] = null;
103108
if (message[EVENT_NAMES] && message[EVENT_NAMES].length)
104109
{
110+
ctx.expanded_map[rt_id] = [];
105111
ctx.rt_map[message[RUNTIME_ID]] =
106112
{
107-
rt_id: message[RUNTIME_ID],
108-
obj_id: message[OBJECT_ID],
113+
rt_id: rt_id,
114+
obj_id: obj_id,
109115
window_id: ctx.win_id_map[rt_id],
110116
event_names: message[EVENT_NAMES].map(function(name)
111117
{
112-
return new cls.EventName(name);
113-
}),
118+
var ev_n_obj = new cls.EventName(name);
119+
if (this.is_expanded(rt_id, name))
120+
{
121+
ctx.expanded_map[rt_id].push(name);
122+
ev_n_obj.rt_id = rt_id;
123+
ev_n_obj.obj_id = obj_id;
124+
ev_n_obj.model = new cls.InspectableDOMNode(rt_id, obj_id);
125+
var search_cb = this._handle_dom_search.bind(this,
126+
ev_n_obj,
127+
ctx.handle_expand_listener);
128+
ev_n_obj.model.search(name, SEARCH_TYPE_EVENT, 0, 0, search_cb);
129+
}
130+
return ev_n_obj;
131+
}, this),
114132
};
115133
}
116-
117-
if (ctx.rt_id_list.every(function(rt_id) {return ctx.rt_map.hasOwnProperty(rt_id); }))
118-
{
119-
for (var i = 0, id; id = ctx.rt_id_list[i]; i++)
120-
{
121-
this._rts[this._get_rt_index(id)] = ctx.rt_map[id];
122-
}
123-
this._view.update();
124-
}
134+
this._check_update_ctx(ctx);
125135
}
126136
else
127137
opera.postError(ui_strings.S_DRAGONFLY_INFO_MESSAGE +
128138
"failed to retrieve the event names in cls.EvenetListeners.")
129139
};
130140

141+
this._handle_expand_listener_on_update = function(ctx, ev_name_obj)
142+
{
143+
var list = ctx.expanded_map[ev_name_obj.rt_id];
144+
var index = list.indexOf(ev_name_obj.name);
145+
if (index > -1)
146+
list.splice(index, 1);
147+
else
148+
opera.postError(ui_strings.S_DRAGONFLY_INFO_MESSAGE +
149+
"_handle_expand_listener_on_update failed in cls.EvenetListeners.")
150+
151+
this._check_update_ctx(ctx);
152+
};
153+
154+
this._check_update_ctx = function(ctx)
155+
{
156+
var check_rt = function(rt_id)
157+
{
158+
return ctx.rt_map.hasOwnProperty(rt_id) &&
159+
(!ctx.rt_map[rt_id] || (ctx.expanded_map[rt_id] &&
160+
ctx.expanded_map[rt_id].length === 0));
161+
};
162+
if (ctx.rt_id_list.every(check_rt))
163+
{
164+
for (var i = 0, id; id = ctx.rt_id_list[i]; i++)
165+
{
166+
this._rts[this._get_rt_index(id)] = ctx.rt_map[id];
167+
}
168+
this._view.update();
169+
}
170+
};
171+
131172
this._handle_dom_search = function(ev_name_obj, cb)
132173
{
133174
var tag = this._tagman.set_callback(this, this._handle_obj_search, [ev_name_obj, cb]);
@@ -147,11 +188,18 @@ cls.EvenetListeners = function(view)
147188
? {win_id: ev_target[OBJECT_ID],
148189
listeners: ev_target[EVENT_LISTENERS]}
149190
: null;
150-
ev_name_obj.expanded = true;
191+
ev_name_obj.is_expanded = true;
192+
193+
if (!this._expand_tree[ev_name_obj.rt_id])
194+
this._expand_tree[ev_name_obj.rt_id] = {};
195+
196+
this._expand_tree[ev_name_obj.rt_id][ev_name_obj.name] = true;
197+
151198
if (cb)
152199
cb(ev_name_obj);
153200
else
154201
this._view.update();
202+
155203
}
156204
else
157205
opera.postError(ui_strings.S_DRAGONFLY_INFO_MESSAGE +
@@ -224,17 +272,41 @@ cls.EvenetListeners = function(view)
224272
ev_n.rt_id = rt_id;
225273
ev_n.obj_id = obj_id;
226274
ev_n.model = new cls.InspectableDOMNode(rt_id, obj_id);
227-
var cb = this._handle_dom_search.bind(this, ev_n, cb);
228-
ev_n.model.search(ev_name, SEARCH_TYPE_EVENT, 0, 0, cb);
275+
var search_cb = this._handle_dom_search.bind(this, ev_n, cb);
276+
ev_n.model.search(ev_name, SEARCH_TYPE_EVENT, 0, 0, search_cb);
229277
}
230278
else
231279
opera.postError(ui_strings.S_DRAGONFLY_INFO_MESSAGE +
232280
"failed to find event names object in cls.EvenetListeners.")
233281

234282
};
235283

284+
this.collapse_listeners = function(rt_id, ev_name)
285+
{
286+
var ev_n_obj = this._get_ev_name_obj(rt_id, ev_name);
287+
if (ev_n_obj)
288+
{
289+
ev_n_obj.model = null;
290+
ev_n_obj.rt_listeners = null;
291+
ev_n_obj.is_expanded = false;
292+
293+
if (this._expand_tree[rt_id])
294+
this._expand_tree[rt_id][ev_name] = false;
295+
}
296+
};
297+
298+
this.is_expanded = function(rt_id, name)
299+
{
300+
return this._expand_tree[rt_id]
301+
? Boolean(this._expand_tree[rt_id][name])
302+
: false;
303+
};
304+
236305
this._init = function(view)
237306
{
307+
this._rts = [];
308+
this._win_id_map = {};
309+
this._expand_tree = {};
238310
this._view = view;
239311
this._tagman = window.tag_manager;
240312
this._esdb = window.services["ecmascript-debugger"];

src/ecma-debugger/evlistenertooltip/evlistenertemplates.js

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -29,13 +29,15 @@
2929
{
3030
return (
3131
["li",
32-
["h2",
32+
["h3",
3333
["input", "type", "button",
3434
"class", "folder-key"],
3535
ev_name_obj.name,
36-
"handler", "get-ev-listeners",
36+
"handler", "toggle-ev-listeners",
3737
"data-ev-name", ev_name_obj.name,
38-
"class", "ev-listener-type"]]);
38+
"class", "ev-listener-type"],
39+
ev_name_obj.is_expanded ? this.ev_all_listeners(ev_name_obj) : []
40+
]);
3941
};
4042

4143
this.ev_listeners = function(listener_list, rt_id)

src/ecma-debugger/evlistenertooltip/viewevlisteners.js

Lines changed: 22 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -17,21 +17,39 @@ cls.EventListenersView = function(id, name, container_class)
1717
}
1818
};
1919

20-
this._get_event_listeners = function(event, target)
20+
this._toggle_event_listeners = function(event, target)
2121
{
2222
var rt_id = Number(target.get_ancestor_attr("data-rt-id"));
2323
var obj_id = Number(target.get_ancestor_attr("data-obj-id"));
2424
var ev_name = target.get_ancestor_attr("data-ev-name");
2525
var li_ele = target.get_ancestor("li");
2626
if (rt_id && obj_id && ev_name && li_ele)
2727
{
28-
var cb = this._show_ev_listeners.bind(this, li_ele);
29-
this._data.expand_listeners(rt_id, obj_id, ev_name, cb);
28+
if (this._data.is_expanded(rt_id, ev_name))
29+
{
30+
var ls = li_ele.querySelector(".ev-all-listeners");
31+
if (ls)
32+
ls.parentNode.removeChild(ls);
33+
34+
var input = li_ele.querySelector("input");
35+
if (input)
36+
input.style.removeProperty("background-position");
37+
38+
this._data.collapse_listeners(rt_id, ev_name);
39+
}
40+
else
41+
{
42+
var cb = this._show_ev_listeners.bind(this, li_ele);
43+
this._data.expand_listeners(rt_id, obj_id, ev_name, cb);
44+
}
3045
}
3146
};
3247

3348
this._update_ev_listeners = function(event, target)
3449
{
50+
// TODO testing
51+
target.get_ancestor("container").innerHTML = "";
52+
3553
this._data.update();
3654
};
3755

@@ -54,7 +72,7 @@ cls.EventListenersView = function(id, name, container_class)
5472
this.init(id, name, container_class);
5573
this._data = new cls.EvenetListeners(this);
5674
var evh = window.event_handlers;
57-
evh.click["get-ev-listeners"] = this._get_event_listeners.bind(this);
75+
evh.click["toggle-ev-listeners"] = this._toggle_event_listeners.bind(this);
5876
evh.click["update-ev-listeners"] = this._update_ev_listeners.bind(this);
5977
};
6078

src/ui-style/debugger_style.css

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1625,6 +1625,11 @@ d
16251625
box-shadow: 1px 1px 2px rgba(0, 0, 0, 0.3);
16261626
}
16271627

1628+
.ev-listener-type
1629+
{
1630+
font: inherit;
1631+
}
1632+
16281633
.ev-listener
16291634
{
16301635
margin: 0;

0 commit comments

Comments
 (0)