~launchpad-pqm/launchpad/devel

« back to all changes in this revision

Viewing changes to lib/lp/app/javascript/lazr/actions/actions.js

Delete unused lazrjs files

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/* Copyright (c) 2009, Canonical Ltd. All rights reserved. */
2
 
 
3
 
YUI.add('lazr.actions', function(Y) {
4
 
 
5
 
Y.namespace('lazr.actions');
6
 
 
7
 
var ACTION = "action",
8
 
    ACTIONCLASS = "Action",
9
 
    ACTIONS = "actions",
10
 
    ACTIONS_HELPER = "ActionsHelper",
11
 
    ACTIONS_ID = "actionsId",
12
 
    ITEM = "item",
13
 
    ITEMCLASSNAME = "itemClassName",
14
 
    LABEL = "label",
15
 
    LAZR_ACTION_DISABLED = 'lazr-action-disabled',
16
 
    LINK = "link",
17
 
    LINKCLASSNAME = "linkClassName",
18
 
    PERMISSION = "permission",
19
 
    RUNNING = "running",
20
 
    TITLE = "title";
21
 
 
22
 
/*
23
 
 * The Actions and ActionsHelper widgets allow for creating arbitrary collections of behavioral
24
 
 * links and situating them in DOM elements on the page. In the absence of a label attribute,
25
 
 * they can be presented with CSS sprites for graphical representation. When actions are running,
26
 
 * they have their primary linkClassName CSS class replaced with lazr-waiting, which can be
27
 
 * styled as needed (spinner, hidden, greyed-out, &c). Each action can be governed by a
28
 
 * permission, which will fire at the time of rendering and, if failing, decorate the action with
29
 
 * the lazr-action-disabled class, which can be styled as needed (hidden, greyed-out, &c).
30
 
*/
31
 
 
32
 
/*
33
 
 * The ActionsHelper widget collects and delegates Action
34
 
 * widgets associated with a common Node
35
 
 *
36
 
 * @class ActionsHelper
37
 
 */
38
 
var ActionsHelper = function(config) {
39
 
    ActionsHelper.superclass.constructor.apply(this, arguments);
40
 
};
41
 
 
42
 
ActionsHelper.NAME = ACTIONS_HELPER;
43
 
 
44
 
ActionsHelper.ATTRS = {
45
 
    actions: { valueFn: function() { return []; }},
46
 
    actionsId: { valueFn: function() { return Y.guid(); }},
47
 
};
48
 
 
49
 
Y.extend(ActionsHelper, Y.Base, {
50
 
    /**
51
 
     * Render actions
52
 
     * <p>
53
 
     * This method is called to render each of its Actions in turn, in the specified node.
54
 
     * </p>
55
 
     *
56
 
     * @method render
57
 
     * @param node {Node} The node that should contain the ActionsHelper
58
 
     */
59
 
    render: function(node) {
60
 
        var doc = Y.config.doc;
61
 
        var actions = this.get(ACTIONS);
62
 
        var actionsId = this.get(ACTIONS_ID);
63
 
 
64
 
        // Check if we already have an instance of the
65
 
        // container in the DOM.
66
 
        var actionsContainer = Y.one("#" + actionsId);
67
 
 
68
 
        if (actionsContainer) {
69
 
            // If the container already exists in the DOM,
70
 
            // unattach it so that it can be moved to a
71
 
            // new parent.
72
 
            actionsContainer.remove()
73
 
        } else {
74
 
            actionsContainer = new Y.Node.create(
75
 
                "<ul id='" + actionsId + "' />");
76
 
        }
77
 
        // If there are no icons to be displayed, don't bother
78
 
        // creating the container.
79
 
        if (actions.length) {
80
 
            // Render each action as a separate item inside
81
 
            // the container.
82
 
            for (var i=0; i<actions.length; i++){
83
 
                var action = actions[i];
84
 
                action.render(actionsContainer);
85
 
            }
86
 
        }
87
 
 
88
 
        // Finally, if a container was created or an existing
89
 
        // one was found, append it to the Document Fragment
90
 
        // for later attachment to the new destination node.
91
 
        if (actionsContainer !== null) {
92
 
            node.appendChild(Y.Node.getDOMNode(actionsContainer));
93
 
        }
94
 
    },
95
 
});
96
 
 
97
 
Y.lazr.actions.ActionsHelper = ActionsHelper;
98
 
 
99
 
/**
100
 
 * This class provides a self-protecting action, governed by permissions,  attached
101
 
 * to a link that can have its style updated when running.
102
 
 *
103
 
 * @class Action
104
 
 * @constructor
105
 
 */
106
 
var Action = function(config) {
107
 
    Action.superclass.constructor.apply(this, arguments);
108
 
};
109
 
 
110
 
/**
111
 
 * Dictionary of selectors to define subparts of the widget that we care about.
112
 
 * YUI calls ATTRS.set(foo) for each foo defined here
113
 
 *
114
 
 * @property Action.NAME
115
 
 * @type String
116
 
 * @static
117
 
 */
118
 
Action.NAME = ACTIONCLASS;
119
 
 
120
 
Action.ATTRS = {
121
 
    /**
122
 
     * A function representing the underlying behavior of this action.
123
 
     *
124
 
     * @attribute action
125
 
     * @type Function
126
 
     */
127
 
    action: {
128
 
        value: null
129
 
    },
130
 
 
131
 
    /**
132
 
     * A function which runs at render time, evaluating to true or fase, determining
133
 
     * whether or not the action should be disabled.
134
 
     *
135
 
     * @attribute permission
136
 
     * @type Function
137
 
     */
138
 
    permission: {
139
 
        value: null
140
 
    },
141
 
 
142
 
    /**
143
 
     * Optional text label for the Action. If present, it will be the text of the
144
 
     * anchor tag
145
 
     *
146
 
     * @attribute label
147
 
     * @type String
148
 
     */
149
 
    label: {
150
 
        value: null
151
 
    },
152
 
 
153
 
    /**
154
 
     * Title attribute of the inner anchor tag
155
 
     *
156
 
     * @attribute title
157
 
     * @type String
158
 
     */
159
 
    title: {
160
 
        value: null
161
 
    },
162
 
 
163
 
    /**
164
 
     * A special CSS class name for the list element of the Action
165
 
     *
166
 
     * @attribute itemClassName
167
 
     * @type String
168
 
     */
169
 
    itemClassName: {
170
 
        value: null
171
 
    },
172
 
 
173
 
    /**
174
 
     * A special CSS class name for the inner anchor element of the Action, will get
175
 
     * swapped out with Y.lazr.ui.CSS_WAITING when the action is running.
176
 
     *
177
 
     * @attribute linkClassName
178
 
     * @type String
179
 
     */
180
 
    linkClassName: {
181
 
        value: null
182
 
    },
183
 
 
184
 
    /**
185
 
     * A flag determining whether the current Action is engaged in its action
186
 
     *
187
 
     * @attribute running
188
 
     * @type Boolean
189
 
     */
190
 
    running: {
191
 
        value: false,
192
 
        setter: function(v) { return this._updateRunState(v); },
193
 
        getter: function(v) { return v; }
194
 
    },
195
 
 
196
 
    /**
197
 
     * A list element, decorated with our CSS class and with our link attached.
198
 
     *
199
 
     * @attribute item
200
 
     * @type Node
201
 
     */
202
 
    item: {
203
 
        valueFn: function() { return this._createItem(); }
204
 
    },
205
 
 
206
 
    /**
207
 
     * An anchor element, decorated with our CSS class and with our behavior attached.
208
 
     *
209
 
     * @attribute link
210
 
     * @type Node
211
 
     */
212
 
    link: {
213
 
        valueFn: function() { return this._createLink(); }
214
 
    }
215
 
 
216
 
};
217
 
 
218
 
Y.extend(Action, Y.Base, {
219
 
 
220
 
    /**
221
 
     * Helper method to toggle the CSS_WAITING class on the link element
222
 
     *
223
 
     * @method
224
 
     * @private
225
 
     */
226
 
    _updateRunState: function(isRunning) {
227
 
        // when we get set to true:
228
 
        //   - turn our icon to a spinner, if appropriate
229
 
        if (this.get(LINKCLASSNAME) !== null) {
230
 
            if (isRunning) {
231
 
                this.get(LINK).replaceClass(
232
 
                    this.get(LINKCLASSNAME),
233
 
                    Y.lazr.ui.CSS_WAITING);
234
 
            } else {
235
 
                this.get(LINK).replaceClass(
236
 
                    Y.lazr.ui.CSS_WAITING,
237
 
                    this.get(LINKCLASSNAME));
238
 
            }
239
 
        }
240
 
        return isRunning;
241
 
    },
242
 
 
243
 
    /**
244
 
     * Helper method to create the link element, and perform initial decoration
245
 
     *
246
 
     * @method
247
 
     * @private
248
 
     */
249
 
    _createLink: function() {
250
 
        var label = this.get(LABEL);
251
 
        var title = this.get(TITLE);
252
 
        var linkClassName = this.get(LINKCLASSNAME);
253
 
        var link = Y.Node.create(
254
 
        "<a href='#' alt='" + title +
255
 
            "' title='" + title + "'></a>");
256
 
        link.on("click", this.actionRunner, this);
257
 
 
258
 
        if (label !== null) {
259
 
            link.append(Y.Node.create(label));
260
 
        }
261
 
 
262
 
        if (linkClassName !== null) {
263
 
            link.addClass(linkClassName);
264
 
        }
265
 
 
266
 
        return link;
267
 
    },
268
 
 
269
 
    /**
270
 
     * Helper method to create the list item element, and perform initial decoration
271
 
     *
272
 
     * @method
273
 
     * @private
274
 
     */
275
 
    _createItem: function() {
276
 
        var itemClassName = this.get(ITEMCLASSNAME);
277
 
        var link = this.get(LINK);
278
 
        var item = Y.Node.create('<li/>'); 
279
 
 
280
 
        if (itemClassName !== null) {
281
 
            item.addClass(itemClassName);
282
 
        }
283
 
 
284
 
        item.append(link);
285
 
 
286
 
        return item;
287
 
    },
288
 
 
289
 
    /**
290
 
     * Render the action and attach it to a node
291
 
     *
292
 
     * @method render
293
 
     */
294
 
    render: function(node) {
295
 
        // Build the link, labeling it if necessary
296
 
        // Compose the item, decorating it if necessary
297
 
        var item = this.get(ITEM);
298
 
        var permission = this.get(PERMISSION);
299
 
 
300
 
        if (permission && !permission()) {
301
 
            item.addClass(LAZR_ACTION_DISABLED);
302
 
        } else {
303
 
            item.removeClass(LAZR_ACTION_DISABLED);
304
 
        }
305
 
 
306
 
        // Place the item
307
 
        node.append(item);
308
 
    },
309
 
 
310
 
    /**
311
 
     * Wrap the actual function so that it short-circuits if the action is currently
312
 
     * running
313
 
     *
314
 
     * @method actionRunner
315
 
     */
316
 
    actionRunner: function() {
317
 
        if (!this.get(RUNNING)) {
318
 
            // Not running, fire.
319
 
            this.get(ACTION)();
320
 
        }
321
 
    }
322
 
});
323
 
 
324
 
Y.lazr.actions.Action = Action;
325
 
 
326
 
}, "0.1.", {"requires": ["oop", "base", "node", "lazr.base"]});