~bac/juju-gui/trunkcopy

« back to all changes in this revision

Viewing changes to lib/yui/api/assets/js/api-list.js

  • Committer: kapil.foss at gmail
  • Date: 2012-07-13 18:45:59 UTC
  • Revision ID: kapil.foss@gmail.com-20120713184559-2xl7be17egsrz0c9
reshape

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
YUI.add('api-list', function (Y) {
2
 
 
3
 
var Lang   = Y.Lang,
4
 
    YArray = Y.Array,
5
 
 
6
 
    APIList = Y.namespace('APIList'),
7
 
 
8
 
    classesNode    = Y.one('#api-classes'),
9
 
    inputNode      = Y.one('#api-filter'),
10
 
    modulesNode    = Y.one('#api-modules'),
11
 
    tabviewNode    = Y.one('#api-tabview'),
12
 
 
13
 
    tabs = APIList.tabs = {},
14
 
 
15
 
    filter = APIList.filter = new Y.APIFilter({
16
 
        inputNode : inputNode,
17
 
        maxResults: 1000,
18
 
 
19
 
        on: {
20
 
            results: onFilterResults
21
 
        }
22
 
    }),
23
 
 
24
 
    search = APIList.search = new Y.APISearch({
25
 
        inputNode : inputNode,
26
 
        maxResults: 100,
27
 
 
28
 
        on: {
29
 
            clear  : onSearchClear,
30
 
            results: onSearchResults
31
 
        }
32
 
    }),
33
 
 
34
 
    tabview = APIList.tabview = new Y.TabView({
35
 
        srcNode  : tabviewNode,
36
 
        panelNode: '#api-tabview-panel',
37
 
        render   : true,
38
 
 
39
 
        on: {
40
 
            selectionChange: onTabSelectionChange
41
 
        }
42
 
    }),
43
 
 
44
 
    focusManager = APIList.focusManager = tabviewNode.plug(Y.Plugin.NodeFocusManager, {
45
 
        circular   : true,
46
 
        descendants: '#api-filter, .yui3-tab-panel-selected .api-list-item a, .yui3-tab-panel-selected .result a',
47
 
        keys       : {next: 'down:40', previous: 'down:38'}
48
 
    }).focusManager,
49
 
 
50
 
    LIST_ITEM_TEMPLATE =
51
 
        '<li class="api-list-item {typeSingular}">' +
52
 
            '<a href="{rootPath}{typePlural}/{name}.html">{displayName}</a>' +
53
 
        '</li>';
54
 
 
55
 
// -- Init ---------------------------------------------------------------------
56
 
 
57
 
// Duckpunch FocusManager's key event handling to prevent it from handling key
58
 
// events when a modifier is pressed.
59
 
Y.before(function (e, activeDescendant) {
60
 
    if (e.altKey || e.ctrlKey || e.metaKey || e.shiftKey) {
61
 
        return new Y.Do.Prevent();
62
 
    }
63
 
}, focusManager, '_focusPrevious', focusManager);
64
 
 
65
 
Y.before(function (e, activeDescendant) {
66
 
    if (e.altKey || e.ctrlKey || e.metaKey || e.shiftKey) {
67
 
        return new Y.Do.Prevent();
68
 
    }
69
 
}, focusManager, '_focusNext', focusManager);
70
 
 
71
 
// Create a mapping of tabs in the tabview so we can refer to them easily later.
72
 
tabview.each(function (tab, index) {
73
 
    var name = tab.get('label').toLowerCase();
74
 
 
75
 
    tabs[name] = {
76
 
        index: index,
77
 
        name : name,
78
 
        tab  : tab
79
 
    };
80
 
});
81
 
 
82
 
// Switch tabs on Ctrl/Cmd-Left/Right arrows.
83
 
tabviewNode.on('key', onTabSwitchKey, 'down:37,39');
84
 
 
85
 
// Focus the filter input when the `/` key is pressed.
86
 
Y.one(Y.config.doc).on('key', onSearchKey, 'down:83');
87
 
 
88
 
// Keep the Focus Manager up to date.
89
 
inputNode.on('focus', function () {
90
 
    focusManager.set('activeDescendant', inputNode);
91
 
});
92
 
 
93
 
// Update all tabview links to resolved URLs.
94
 
tabview.get('panelNode').all('a').each(function (link) {
95
 
    link.setAttribute('href', link.get('href'));
96
 
});
97
 
 
98
 
// -- Private Functions --------------------------------------------------------
99
 
function getFilterResultNode() {
100
 
    return filter.get('queryType') === 'classes' ? classesNode : modulesNode;
101
 
}
102
 
 
103
 
// -- Event Handlers -----------------------------------------------------------
104
 
function onFilterResults(e) {
105
 
    var frag         = Y.one(Y.config.doc.createDocumentFragment()),
106
 
        resultNode   = getFilterResultNode(),
107
 
        typePlural   = filter.get('queryType'),
108
 
        typeSingular = typePlural === 'classes' ? 'class' : 'module';
109
 
 
110
 
    if (e.results.length) {
111
 
        YArray.each(e.results, function (result) {
112
 
            frag.append(Lang.sub(LIST_ITEM_TEMPLATE, {
113
 
                rootPath    : APIList.rootPath,
114
 
                displayName : filter.getDisplayName(result.highlighted),
115
 
                name        : result.text,
116
 
                typePlural  : typePlural,
117
 
                typeSingular: typeSingular
118
 
            }));
119
 
        });
120
 
    } else {
121
 
        frag.append(
122
 
            '<li class="message">' +
123
 
                'No ' + typePlural + ' found.' +
124
 
            '</li>'
125
 
        );
126
 
    }
127
 
 
128
 
    resultNode.empty(true);
129
 
    resultNode.append(frag);
130
 
 
131
 
    focusManager.refresh();
132
 
}
133
 
 
134
 
function onSearchClear(e) {
135
 
 
136
 
    focusManager.refresh();
137
 
}
138
 
 
139
 
function onSearchKey(e) {
140
 
    var target = e.target;
141
 
 
142
 
    if (target.test('input,select,textarea')
143
 
            || target.get('isContentEditable')) {
144
 
        return;
145
 
    }
146
 
 
147
 
    e.preventDefault();
148
 
 
149
 
    inputNode.focus();
150
 
    focusManager.refresh();
151
 
}
152
 
 
153
 
function onSearchResults(e) {
154
 
    var frag = Y.one(Y.config.doc.createDocumentFragment());
155
 
 
156
 
    if (e.results.length) {
157
 
        YArray.each(e.results, function (result) {
158
 
            frag.append(result.display);
159
 
        });
160
 
    } else {
161
 
        frag.append(
162
 
            '<li class="message">' +
163
 
                'No results found. Maybe you\'ll have better luck with a ' +
164
 
                'different query?' +
165
 
            '</li>'
166
 
        );
167
 
    }
168
 
 
169
 
 
170
 
    focusManager.refresh();
171
 
}
172
 
 
173
 
function onTabSelectionChange(e) {
174
 
    var tab  = e.newVal,
175
 
        name = tab.get('label').toLowerCase();
176
 
 
177
 
    tabs.selected = {
178
 
        index: tab.get('index'),
179
 
        name : name,
180
 
        tab  : tab
181
 
    };
182
 
 
183
 
    switch (name) {
184
 
    case 'classes': // fallthru
185
 
    case 'modules':
186
 
        filter.setAttrs({
187
 
            minQueryLength: 0,
188
 
            queryType     : name
189
 
        });
190
 
 
191
 
        search.set('minQueryLength', -1);
192
 
 
193
 
        // Only send a request if this isn't the initially-selected tab.
194
 
        if (e.prevVal) {
195
 
            filter.sendRequest(filter.get('value'));
196
 
        }
197
 
        break;
198
 
 
199
 
    case 'everything':
200
 
        filter.set('minQueryLength', -1);
201
 
        search.set('minQueryLength', 1);
202
 
 
203
 
        if (search.get('value')) {
204
 
            search.sendRequest(search.get('value'));
205
 
        } else {
206
 
            inputNode.focus();
207
 
        }
208
 
        break;
209
 
 
210
 
    default:
211
 
        // WTF? We shouldn't be here!
212
 
        filter.set('minQueryLength', -1);
213
 
        search.set('minQueryLength', -1);
214
 
    }
215
 
 
216
 
    if (focusManager) {
217
 
        setTimeout(function () {
218
 
            focusManager.refresh();
219
 
        }, 1);
220
 
    }
221
 
}
222
 
 
223
 
function onTabSwitchKey(e) {
224
 
    var currentTabIndex = tabs.selected.index;
225
 
 
226
 
    if (!(e.ctrlKey || e.metaKey)) {
227
 
        return;
228
 
    }
229
 
 
230
 
    e.preventDefault();
231
 
 
232
 
    switch (e.keyCode) {
233
 
    case 37: // left arrow
234
 
        if (currentTabIndex > 0) {
235
 
            tabview.selectChild(currentTabIndex - 1);
236
 
            inputNode.focus();
237
 
        }
238
 
        break;
239
 
 
240
 
    case 39: // right arrow
241
 
        if (currentTabIndex < (Y.Object.size(tabs) - 2)) {
242
 
            tabview.selectChild(currentTabIndex + 1);
243
 
            inputNode.focus();
244
 
        }
245
 
        break;
246
 
    }
247
 
}
248
 
 
249
 
}, '3.4.0', {requires: [
250
 
    'api-filter', 'api-search', 'event-key', 'node-focusmanager', 'tabview'
251
 
]});