93 |
94 | This is a ListView header
95 | This list view item's rating is: {{item.data.rating}}
96 |
97 | This is a ListView footer
98 |
99 |
100 | ### Menu and MenuCommand
101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 |
109 | ### Pivot and PivotItem
110 |
111 |
112 | Custom Left Header
113 |
114 | Pivots are useful for varied content
115 |
116 |
117 | This Pivot is boring however, it just has things like data bindings: {{ratings.length}}
118 |
119 |
120 | Because it's only purpose is to show how to create a Pivot
121 |
122 | Custom Right Header
123 |
124 |
125 | ### Rating
126 |
127 | The current rating is: {{ratings[0].rating}}.
128 |
129 |
130 | ### SemanticZoom
131 |
132 |
133 |
134 |
135 | The data is: {{item.data}}
136 |
137 |
138 | The group is: {{item.key}}
139 |
140 |
141 |
142 |
143 | The group is: {{item.key}}
144 |
145 |
146 |
147 |
148 | ### SplitView and optional SplitViewPaneToggle
149 | angular.module("yourAngularApp", ["winjs"]).controller("yourController", function ($scope) {
150 | $scope.splitViewElement = document.getElementById("splitView");
151 | });
152 |
153 |
154 |
155 | SplitView Navigation Pane
156 |
157 |
158 |
159 | SplitView Content Area
160 |
161 |
162 | ### ToolBar
163 |
164 |
165 |
166 |
167 |
168 |
169 |
170 |
171 |
172 | ### TimePicker
173 |
174 |
175 |
176 | ### ToggleSwitch
177 |
178 |
179 | The state is: {{toggleState}}
180 |
181 |
182 | ### Tooltip
183 |
184 |
185 | This can have arbitrary content, like images...
186 | This has a tooltip, hover and see...
187 |
188 |
189 | ### WinControl
190 |
191 |
192 |
193 | This Pivot is showing how to access its winControl through Angular.
194 | The winControl can now be accessed as a variable on the Angular scope, using the same name that was
195 | specified in the directive. In this case, $scope.pivotWinControl
196 |
197 |
198 |
199 | How to run unit tests
200 | -------------------------
201 |
202 | ### Install Node
203 | In order run tests, ensure that you have [Node.js](http://nodejs.org/download/) installed.
204 |
205 | ### Run the tests
206 | From the local angular-winjs repository
207 | ```
208 | npm install
209 | npm test
210 | ```
211 |
212 |
213 | Notes
214 | -----
215 |
216 | For all of the controls you can bind to: all public events, and camel cased property names, conveniently map to attributes.
217 | - ```appBar.closedDisplayMode = "compact"``` maps to ``````
218 | - ```flipView.onpageselected = pagesSelected()``` maps to ``````
219 |
--------------------------------------------------------------------------------
/bower.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "angular-winjs",
3 | "homepage": "https://github.com/winjs/angular-winjs",
4 | "authors": [
5 | "Microsoft Corporation and other contributors"
6 | ],
7 | "description": "This code is a wrapper which facilitates usage of WinJS UI controls in an Angular application.",
8 | "main": "js/angular-winjs.js",
9 | "keywords": [
10 | "winjs",
11 | "angular",
12 | "AngularJS"
13 | ],
14 | "license": "MIT",
15 | "ignore": [
16 | "**/.*",
17 | "node_modules",
18 | "bower_components",
19 | "test",
20 | "tests",
21 | "package.json",
22 | "karma.config.js",
23 | "*.nuspec",
24 | "Gruntfile.js"
25 | ]
26 | }
--------------------------------------------------------------------------------
/js/angular-winjs.js:
--------------------------------------------------------------------------------
1 | // Copyright (c) Microsoft Corp. All Rights Reserved. Licensed under the MIT License. See License.txt in the project root for license information.
2 | (function (global) {
3 | "use strict";
4 |
5 | // setImmediate is not implemented in all browsers. If it doesn't exist, use setTimeout(_, 0) instead.
6 | var setImmediate = window.setImmediate;
7 | if (!setImmediate) {
8 | setImmediate = function (f) {
9 | return setTimeout(f, 0);
10 | };
11 | }
12 |
13 | // ObjectIndexMap is used in the list binding code. On browsers with Map support we simply use the built in
14 | // primitive, for list elements which are extensible we instead map from the list elements to their
15 | // current index (note that we must do the full mapping on every diff in order to ensure we don't
16 | // see stale indicies), and for non-extensible objects we fall back to using an array with O(N)
17 | // lookup behavior on get.
18 | // ObjectIndexMap is only intended to be used in the list binding code below. This helper
19 | // is limited in that only one key object can be in any map at a time.
20 | var ObjectIndexMap = window.Map;
21 | if (!ObjectIndexMap) {
22 | // A simple value -> integer map
23 | ObjectIndexMap = function () {
24 | this._nonExtensibleBacking = [];
25 | };
26 | ObjectIndexMap.key = "$$$$mapkey";
27 | ObjectIndexMap.prototype.has = function (key) {
28 | if (Object.isExtensible(key)) {
29 | return ObjectIndexMap.key in key;
30 | } else {
31 | return this._nonExtensibleBacking.indexOf(key) !== -1;
32 | }
33 | };
34 | ObjectIndexMap.prototype.get = function (key) {
35 | if (Object.isExtensible(key)) {
36 | return key[ObjectIndexMap.key];
37 | } else {
38 | return this._nonExtensibleBacking.indexOf(key);
39 | }
40 | };
41 | ObjectIndexMap.prototype.set = function (key, value) {
42 | if (Object.isExtensible(key)) {
43 | key[ObjectIndexMap.key] = value;
44 | } else {
45 | this._nonExtensibleBacking[value] = key;
46 | }
47 | };
48 | }
49 |
50 | // Pure utility functions
51 | function getElementRoot(element) {
52 | var curr = element;
53 | while (curr.parentNode) {
54 | curr = curr.parentNode;
55 | }
56 | return curr;
57 | }
58 |
59 | function select(selector, element) {
60 | return document.querySelector(selector) || getElementRoot(element).querySelector(selector);
61 | }
62 |
63 | // Directive utilities
64 | function addDestroyListener($scope, control, bindings, destroyed) {
65 | $scope.$on("$destroy", function () {
66 | (destroyed && destroyed());
67 |
68 | bindings.forEach(function (w) { w(); });
69 |
70 | if (control.dispose) {
71 | control.dispose();
72 | }
73 | });
74 | }
75 |
76 | function apply($scope, f) {
77 | switch ($scope.$root.$$phase) {
78 | case "$apply":
79 | case "$digest":
80 | f();
81 | break;
82 | default:
83 | $scope.$apply(function () {
84 | f();
85 | });
86 | break;
87 | }
88 | }
89 |
90 | function exists(control) {
91 | return !!Object.getOwnPropertyDescriptor(WinJS.UI, control);
92 | }
93 |
94 | function list($scope, key, getControl, getList, bindings) {
95 | var value = $scope[key];
96 | if (value && Array.isArray(value)) {
97 | var originalArray = value;
98 | var bindingList = new WinJS.Binding.List(originalArray);
99 | value = bindingList;
100 |
101 | bindings.push($scope.$watchCollection(key, function (array) {
102 | var list = getList();
103 | if (!list) {
104 | return;
105 | }
106 | if (!array) {
107 | list.length = 0;
108 | return;
109 | }
110 | var targetIndicies = new ObjectIndexMap();
111 | for (var i = 0, len = array.length; i < len; i++) {
112 | targetIndicies.set(array[i], i);
113 | }
114 | var arrayIndex = 0, listIndex = 0;
115 | while (arrayIndex < array.length) {
116 | var arrayData = array[arrayIndex];
117 | if (listIndex >= list.length) {
118 | list.push(arrayData);
119 | } else {
120 | while (listIndex < list.length) {
121 | var listData = list.getAt(listIndex);
122 | if (listData === arrayData) {
123 | listIndex++;
124 | arrayIndex++;
125 | break;
126 | } else {
127 | if (targetIndicies.has(listData)) {
128 | var targetIndex = targetIndicies.get(listData);
129 | if (targetIndex < arrayIndex) {
130 | // Already in list, remove the duplicate
131 | list.splice(listIndex, 1);
132 | } else {
133 | list.splice(listIndex, 0, arrayData);
134 | arrayIndex++;
135 | listIndex++;
136 | break;
137 | }
138 | } else {
139 | // Deleted, remove from list
140 | list.splice(listIndex, 1);
141 | }
142 | }
143 | }
144 | }
145 | }
146 | // Clip any items which are left over in the tail.
147 | list.length = array.length;
148 | }));
149 |
150 | var deferUpdate = false;
151 | var updateOriginalArray = function () {
152 | if (deferUpdate) {
153 | return;
154 | }
155 |
156 | // Defer here so that we can process all changes to the list in one go.
157 | deferUpdate = true;
158 | WinJS.Utilities._setImmediate(function () {
159 | apply($scope, function () {
160 | originalArray.length = 0;
161 | for (var i = 0, len = bindingList.length; i < len; i++) {
162 | originalArray.push(bindingList.getAt(i));
163 | }
164 | deferUpdate = false;
165 | });
166 | });
167 | }
168 |
169 | // The Binding.List we're creating for the WinJS control can be altered by the control (eg, ListView will reorder the content of its Binding.List in drag and drop scenarios).
170 | // We need to make sure changes to this list propagate back to the original array on the Angular scope. We'll listen to all data changes in the Binding.List
171 | // and change the original array when something changes.
172 | var bindingListMutationEvents = ["itemchanged", "itemmoved", "itemmutated", "itemremoved", "reload"];
173 | bindingListMutationEvents.forEach(function (event) {
174 | bindingList.addEventListener(event, updateOriginalArray);
175 | });
176 | } else {
177 | // The value from $scope[key] can be undefined when this list function first runs.
178 | // If the binding behind that value has already been processed by angular but hasn't been applied to the scope yet, $scope[key] will be undefined,
179 | // but when this watch function is called, oldValue will have the same value as newValue instead of being undefined.
180 | // In most cases we want to avoid reprocessing the list when newValue === oldValue, but we will make an exeption for this case.
181 | // When $scope[key] is falsy, we'll set up the listener to use oldValue if oldValue is valid and it's the listener's first run.
182 | var updateValueOnFirstWatch = (!value);
183 | bindings.push($scope.$watch(key, function (newValue, oldValue) {
184 | if (newValue !== oldValue || (oldValue && updateValueOnFirstWatch)) {
185 | getControl()[key] = list($scope, key, getControl, getList, bindings);
186 | }
187 | updateValueOnFirstWatch = false;
188 | }));
189 | }
190 |
191 | if (value && value.dataSource) {
192 | value = value.dataSource;
193 | }
194 | return value;
195 | }
196 |
197 | function proxy($scope, controller, name) {
198 | Object.defineProperty(controller, name, {
199 | get: function () { return $scope[name]; },
200 | set: function (value) { $scope[name] = value; }
201 | });
202 | }
203 |
204 | // Refer to https://docs.angularjs.org/api/ng/service/$compile for documentation on what "=?" etc. means
205 | function BINDING_anchor($scope, key, element, getControl, bindings) {
206 | bindings.push($scope.$watch(key, function (newValue, oldValue) {
207 | newValue = typeof newValue === "string" ? select(newValue, element) : newValue;
208 | oldValue = typeof oldValue === "string" ? select(oldValue, element) : oldValue;
209 | if (oldValue && oldValue._anchorClick) {
210 | oldValue.removeEventListener("click", oldValue._anchorClick);
211 | oldValue._anchorClick = null;
212 | }
213 | if (newValue && !newValue._anchorClick) {
214 | newValue._anchorClick = function () { getControl().show(); };
215 | newValue.addEventListener("click", newValue._anchorClick);
216 | }
217 | return newValue;
218 | }));
219 | var anchor = $scope[key];
220 | return typeof anchor === "string" ? select(anchor, element) : anchor;
221 | }
222 | BINDING_anchor.binding = "=?";
223 |
224 | function BINDING_dataSource($scope, key, element, getControl, bindings) {
225 | function getList() {
226 | var control = getControl();
227 | if (control) {
228 | var dataSource = control[key];
229 | if (dataSource) {
230 | return dataSource.list;
231 | }
232 | }
233 | }
234 | return list($scope, key, getControl, getList, bindings);
235 | }
236 | BINDING_dataSource.binding = "=?";
237 |
238 | function BINDING_event($scope, key, element, getControl, bindings) {
239 | var lowerName = key.toLowerCase();
240 | bindings.push($scope.$watch(key, function (newValue, oldValue) {
241 | if (newValue !== oldValue) {
242 | getControl()[lowerName] = newValue;
243 | }
244 | }));
245 | var value = $scope[key];
246 | return function (event) {
247 | apply($scope, function () { value({ $event: event }); });
248 | };
249 | }
250 | BINDING_event.binding = "&";
251 |
252 | function BINDING_property($scope, key, element, getControl, bindings) {
253 | bindings.push($scope.$watch(key, function (newValue, oldValue) {
254 | if (newValue !== oldValue) {
255 | (getControl() || {})[key] = newValue;
256 | }
257 | }));
258 | return $scope[key];
259 | }
260 | BINDING_property.binding = "=?";
261 |
262 | function BINDING_readonly_property($scope, key, element, getControl, bindings) {
263 | return $scope[key];
264 | }
265 | BINDING_readonly_property.binding = "=?";
266 |
267 | function BINDING_selection($scope, key, element, getControl, bindings) {
268 | bindings.push($scope.$watchCollection(key, function (selection) {
269 | var value = (getControl() || {})[key];
270 | if (value) {
271 | value.set(selection);
272 | }
273 | }));
274 | return $scope[key];
275 | }
276 | BINDING_selection.binding = "=?";
277 |
278 | function getScopeForAPI(api) {
279 | var scopeDefinition = {};
280 | for (var property in api) {
281 | scopeDefinition[property] = api[property].binding;
282 | }
283 | return scopeDefinition;
284 | }
285 |
286 | function initializeControlBindings($scope, api, controlRoot, getControl) {
287 | var controlOptions = {},
288 | bindings = [];
289 |
290 | for (var property in api) {
291 | var binding = api[property];
292 | var propertyValue = binding($scope, property, controlRoot, getControl, bindings);
293 |
294 | // The API defines event names in camel case. WinJS expects event names to be all lowercase. We'll fix the event names here.
295 | if (binding === BINDING_event) {
296 | property = property.toLowerCase();
297 | }
298 |
299 | if (propertyValue !== undefined) {
300 | // We don't want to try setting read only properties on the WinJS control. BINDING_readonly_property and BINDING_selection are both read only.
301 | // BINDING_selection may not seem like it's read only at first glance, but that's only because we do extra work in this library to make it
302 | // seem like it's gettable and settable in Angular.
303 | if (binding !== BINDING_selection &&
304 | binding !== BINDING_readonly_property) {
305 | controlOptions[property] = propertyValue;
306 | }
307 | }
308 | }
309 |
310 | return {
311 | options: controlOptions,
312 | bindings: bindings
313 | };
314 | }
315 |
316 | function removeDuplicateAttributes(element, api) {
317 | // WinJS has a couple naming collisions with actual DOM attributes. When the control we're constructing has
318 | // these attributes on its DOM element, we'll remove them so the WinJS control can function as appropriate.
319 | var attributesToRemove = ["checked", "disabled", "hidden", "id", "title", "type"];
320 | for (var i = 0, len = attributesToRemove.length; i < len; i++) {
321 | if (api.hasOwnProperty(attributesToRemove[i])) {
322 | element.removeAttribute(attributesToRemove[i]);
323 | }
324 | }
325 | }
326 | function initializeControl($scope, element, controlConstructor, api, extraOptions, onDestroyed) {
327 | removeDuplicateAttributes(element, api);
328 |
329 | var control,
330 | controlDetails = initializeControlBindings($scope, api, element, function () { return control; });
331 |
332 | if (extraOptions) {
333 | for (var option in extraOptions) {
334 | controlDetails.options[option] = extraOptions[option];
335 | }
336 | }
337 |
338 | control = new controlConstructor(element, controlDetails.options);
339 | addDestroyListener($scope, control, controlDetails.bindings, onDestroyed);
340 | return control;
341 | }
342 |
343 | // Shared compile/link functions
344 | function compileTemplate(name) {
345 | // Directive compile function
346 | return function (tElement, tAttrs, transclude) {
347 | var rootElement = document.createElement("div");
348 | Object.keys(tAttrs).forEach(function (key) {
349 | if (key[0] !== '$') {
350 | rootElement.setAttribute(key, tAttrs[key]);
351 | }
352 | });
353 | var immediateToken;
354 | // Directive link function
355 | return function ($scope, elements, attrs, parents) {
356 | var parent = parents.reduce(function (found, item) { return found || item; });
357 | parent[name] = function (itemPromise) {
358 | // Actual item renderer
359 | return WinJS.Promise.as(itemPromise).then(function (item) {
360 | var itemScope = $scope.$new();
361 | itemScope.item = item;
362 | var result = rootElement.cloneNode(false);
363 | transclude(itemScope, function (clonedElement) {
364 | for (var i = 0, len = clonedElement.length; i < len; i++) {
365 | result.appendChild(clonedElement[i]);
366 | }
367 | });
368 | WinJS.Utilities.markDisposable(result, function () {
369 | itemScope.$destroy();
370 | });
371 | immediateToken = immediateToken || setImmediate(function () {
372 | immediateToken = null;
373 | itemScope.$apply();
374 | });
375 | return result;
376 | })
377 | };
378 | };
379 | };
380 | }
381 |
382 | // WinJS module definition
383 | var module = angular.module("winjs", []);
384 |
385 | module.config(['$compileProvider', function ($compileProvider) {
386 | switch (document.location.protocol.toLowerCase()) {
387 | // For reference on URI schemes refer to http://msdn.microsoft.com/en-us/library/windows/apps/xaml/jj655406.aspx
388 | case "ms-appx:":
389 | case "ms-appx-web:":
390 | // Whitelist the Windows Runtime URL schemes so Angular does not flag as 'unsafe'.
391 | var whitelist = /^\s*(http|https|ms-appx|ms-appx-web|ms-appdata):/i;
392 | $compileProvider.imgSrcSanitizationWhitelist(whitelist);
393 | $compileProvider.aHrefSanitizationWhitelist(whitelist);
394 | break;
395 | }
396 | }]);
397 |
398 | module.run(['$rootScope', function ($rootScope) {
399 | var Scope = Object.getPrototypeOf($rootScope);
400 | var Scope$eval = Scope.$eval;
401 | Scope.$eval = function (expr, locals) {
402 | var that = this;
403 | if (window.MSApp && MSApp.execUnsafeLocalFunction) {
404 | return MSApp.execUnsafeLocalFunction(function () {
405 | return Scope$eval.call(that, expr, locals);
406 | });
407 | } else {
408 | return Scope$eval.call(that, expr, locals);
409 | }
410 | };
411 | }]);
412 |
413 | function camelToDash(string) {
414 | return string.replace(/[A-Z]/g, function (letter) {
415 | return "-" + letter.toLowerCase();
416 | });
417 | }
418 |
419 | function createHelperDirective(requires, directiveName) {
420 | var helperClassName = camelToDash(directiveName);
421 | module.directive(directiveName, function () {
422 | return {
423 | require: "^" + requires,
424 | restrict: "E",
425 | replace: true,
426 | transclude: true,
427 | template: ""
428 | };
429 | });
430 | }
431 |
432 | function extractHelperDirectiveElements(parentNode, directiveName) {
433 | var elements = parentNode.querySelectorAll("." + camelToDash(directiveName));
434 | for (var i = 0, len = elements.length; i < len; i++) {
435 | elements[i].parentNode.removeChild(elements[i]);
436 | }
437 | return elements;
438 | }
439 |
440 | function getHelperDirectives(parentNode, directives) {
441 | var directivesFound = {};
442 | directives.forEach(function (directive) {
443 | var matchingElements = extractHelperDirectiveElements(parentNode, directive.directiveName);
444 | if (matchingElements.length > 0) {
445 | directivesFound[directive.controlOptionName] = matchingElements[0];
446 | }
447 | });
448 | return directivesFound;
449 | }
450 |
451 | // Directives
452 | exists("AppBar") && module.directive("winAppBar", ['$parse', function ($parse) {
453 | var api = {
454 | closedDisplayMode: BINDING_property,
455 | data: BINDING_property,
456 | opened: BINDING_property,
457 | placement: BINDING_property,
458 | onAfterClose: BINDING_event,
459 | onAfterOpen: BINDING_event,
460 | onBeforeClose: BINDING_event,
461 | onBeforeOpen: BINDING_event
462 | };
463 | return {
464 | restrict: "E",
465 | replace: true,
466 | scope: getScopeForAPI(api),
467 | template: "",
468 | transclude: true,
469 | link: function ($scope, elements, attrs) {
470 | var control = initializeControl($scope, elements[0], WinJS.UI.AppBar, api);
471 |
472 | function onVisibilityChanged() {
473 | apply($scope, function () {
474 | $scope["opened"] = control["opened"];
475 | });
476 | }
477 |
478 | control.addEventListener("afteropen", onVisibilityChanged);
479 | control.addEventListener("afterclose", onVisibilityChanged);
480 | }
481 | };
482 | }]);
483 |
484 | exists("AppBar") && module.directive("winAppBarCommand", function () {
485 | var api = {
486 | disabled: BINDING_property,
487 | extraClass: BINDING_property,
488 | firstElementFocus: BINDING_property,
489 | flyout: BINDING_property,
490 | hidden: BINDING_property,
491 | icon: BINDING_property,
492 | id: BINDING_property,
493 | label: BINDING_property,
494 | lastElementFocus: BINDING_property,
495 | priority: BINDING_property,
496 | section: BINDING_property,
497 | selected: BINDING_property,
498 | tooltip: BINDING_property,
499 | type: BINDING_property,
500 | onClick: BINDING_event
501 | };
502 | return {
503 | restrict: "E",
504 | replace: true,
505 | scope: getScopeForAPI(api),
506 | template: "",
507 | transclude: true,
508 | link: function ($scope, elements) {
509 | initializeControl($scope, elements[0], WinJS.UI.Command, api);
510 | }
511 | };
512 | });
513 |
514 | exists("AppBar") && module.directive("winAppBarSeparator", function () {
515 | var api = {
516 | disabled: BINDING_property,
517 | extraClass: BINDING_property,
518 | firstElementFocus: BINDING_property,
519 | flyout: BINDING_property,
520 | hidden: BINDING_property,
521 | icon: BINDING_property,
522 | id: BINDING_property,
523 | label: BINDING_property,
524 | lastElementFocus: BINDING_property,
525 | priority: BINDING_property,
526 | section: BINDING_property,
527 | selected: BINDING_property,
528 | tooltip: BINDING_property,
529 | type: BINDING_property,
530 | onClick: BINDING_event
531 | };
532 | return {
533 | restrict: "E",
534 | replace: true,
535 | scope: getScopeForAPI(api),
536 | template: "",
537 | transclude: true,
538 | link: function ($scope, elements) {
539 | initializeControl($scope, elements[0], WinJS.UI.Command, api, { type: "separator" });
540 | }
541 | };
542 | });
543 |
544 | exists("AppBar") && module.directive("winAppBarContent", function () {
545 | var api = {
546 | disabled: BINDING_property,
547 | extraClass: BINDING_property,
548 | firstElementFocus: BINDING_property,
549 | flyout: BINDING_property,
550 | hidden: BINDING_property,
551 | icon: BINDING_property,
552 | id: BINDING_property,
553 | label: BINDING_property,
554 | lastElementFocus: BINDING_property,
555 | priority: BINDING_property,
556 | section: BINDING_property,
557 | selected: BINDING_property,
558 | tooltip: BINDING_property,
559 | type: BINDING_property,
560 | onClick: BINDING_event
561 | };
562 | return {
563 | restrict: "E",
564 | replace: true,
565 | scope: getScopeForAPI(api),
566 | template: "",
567 | transclude: true,
568 | link: function ($scope, elements) {
569 | initializeControl($scope, elements[0], WinJS.UI.Command, api, { type: "content" });
570 | }
571 | };
572 | });
573 |
574 | exists("AutoSuggestBox") && module.directive("winAutoSuggestBox", function () {
575 | var api = {
576 | chooseSuggestionOnEnter: BINDING_property,
577 | disabled: BINDING_property,
578 | placeholderText: BINDING_property,
579 | queryText: BINDING_property,
580 | searchHistoryContext: BINDING_property,
581 | searchHistoryDisabled: BINDING_property,
582 | onQueryChanged: BINDING_event,
583 | onQuerySubmitted: BINDING_event,
584 | onResultSuggestionChosen: BINDING_event,
585 | onSuggestionsRequested: BINDING_event
586 | };
587 | return {
588 | restrict: "E",
589 | replace: true,
590 | scope: getScopeForAPI(api),
591 | template: "",
592 | link: function ($scope, elements, attrs) {
593 | var control = initializeControl($scope, elements[0], WinJS.UI.AutoSuggestBox, api);
594 |
595 | control.addEventListener("querychanged", function () {
596 | apply($scope, function () {
597 | $scope["queryText"] = control["queryText"];
598 | });
599 | });
600 | }
601 | };
602 | });
603 |
604 | exists("BackButton") && module.directive("winBackButton", function () {
605 | return {
606 | restrict: "E",
607 | replace: true,
608 | template: "",
609 | link: function ($scope, elements) {
610 | var control = new WinJS.UI.BackButton(elements[0]);
611 | }
612 | };
613 | });
614 |
615 | exists("CellSpanningLayout") && module.directive("winCellSpanningLayout", function () {
616 | var api = {
617 | groupHeaderPosition: BINDING_property,
618 | groupInfo: BINDING_property,
619 | itemInfo: BINDING_property,
620 | maximumRowsOrColumns: BINDING_property,
621 | orientation: BINDING_property
622 | };
623 | return {
624 | require: "^winListView",
625 | restrict: "E",
626 | replace: true,
627 | template: "",
628 | scope: getScopeForAPI(api),
629 | link: function ($scope, elements, attrs, listView) {
630 | var layout;
631 | var controlBindings = initializeControlBindings($scope, api, null, function () { return layout; })
632 | layout = listView.layout = new WinJS.UI.CellSpanningLayout(controlBindings.options);
633 | addDestroyListener($scope, layout, controlBindings.bindings);
634 | }
635 | };
636 | });
637 |
638 | exists("ContentDialog") && module.directive("winContentDialog", function () {
639 | var api = {
640 | hidden: BINDING_property,
641 | primaryCommandText: BINDING_property,
642 | primaryCommandDisabled: BINDING_property,
643 | secondaryCommandText: BINDING_property,
644 | secondaryCommandDisabled: BINDING_property,
645 | title: BINDING_property,
646 | onAfterHide: BINDING_event,
647 | onAfterShow: BINDING_event,
648 | onBeforeHide: BINDING_event,
649 | onBeforeShow: BINDING_event
650 | };
651 | return {
652 | restrict: "E",
653 | replace: true,
654 | scope: getScopeForAPI(api),
655 | template: "",
656 | transclude: true,
657 | link: function ($scope, elements, attrs) {
658 | var control = initializeControl($scope, elements[0], WinJS.UI.ContentDialog, api);
659 |
660 | function onVisibilityChanged() {
661 | apply($scope, function () {
662 | $scope["hidden"] = control["hidden"];
663 | });
664 | }
665 |
666 | control.addEventListener("afterhide", onVisibilityChanged);
667 | control.addEventListener("aftershow", onVisibilityChanged);
668 | }
669 | };
670 | });
671 |
672 | exists("DatePicker") && module.directive("winDatePicker", function () {
673 | var api = {
674 | calendar: BINDING_property,
675 | current: BINDING_property,
676 | datePattern: BINDING_property,
677 | disabled: BINDING_property,
678 | maxYear: BINDING_property,
679 | minYear: BINDING_property,
680 | monthPattern: BINDING_property,
681 | yearPattern: BINDING_property,
682 | onChange: BINDING_event
683 | };
684 | return {
685 | restrict: "E",
686 | replace: true,
687 | scope: getScopeForAPI(api),
688 | template: "",
689 | link: function ($scope, elements) {
690 | var control = initializeControl($scope, elements[0], WinJS.UI.DatePicker, api);
691 |
692 | control.addEventListener("change", function () {
693 | apply($scope, function () {
694 | $scope["current"] = control["current"];
695 | });
696 | });
697 | }
698 | };
699 | });
700 |
701 | exists("FlipView") && module.directive("winFlipView", function () {
702 | var api = {
703 | currentPage: BINDING_property,
704 | itemDataSource: BINDING_dataSource,
705 | itemSpacing: BINDING_property,
706 | itemTemplate: BINDING_property,
707 | orientation: BINDING_property,
708 | onDataSourceCountChanged: BINDING_event,
709 | onPageCompleted: BINDING_event,
710 | onPageSelected: BINDING_event,
711 | onPageVisibilityChanged: BINDING_event
712 | };
713 | return {
714 | restrict: "E",
715 | replace: true,
716 | scope: getScopeForAPI(api),
717 | template: "",
718 | transclude: true,
719 | controller: ['$scope', function ($scope) {
720 | proxy($scope, this, "itemTemplate");
721 | }],
722 | link: function ($scope, elements, attrs) {
723 | var control = initializeControl($scope, elements[0], WinJS.UI.FlipView, api);
724 |
725 | control.addEventListener("pageselected", function () {
726 | apply($scope, function () {
727 | $scope["currentPage"] = control["currentPage"];
728 | });
729 | });
730 | }
731 | };
732 | });
733 |
734 | exists("Flyout") && module.directive("winFlyout", ['$parse', function ($parse) {
735 | var api = {
736 | alignment: BINDING_property,
737 | anchor: BINDING_anchor,
738 | disabled: BINDING_property,
739 | hidden: BINDING_property,
740 | placement: BINDING_property,
741 | onAfterHide: BINDING_event,
742 | onAfterShow: BINDING_event,
743 | onBeforeHide: BINDING_event,
744 | onBeforeShow: BINDING_event
745 | };
746 | return {
747 | restrict: "E",
748 | replace: true,
749 | scope: getScopeForAPI(api),
750 | template: "",
751 | transclude: true,
752 | link: function ($scope, elements, attrs) {
753 | var control = initializeControl($scope, elements[0], WinJS.UI.Flyout, api);
754 |
755 | function onVisibilityChanged() {
756 | apply($scope, function () {
757 | $scope["hidden"] = control["hidden"];
758 | });
759 | }
760 |
761 | control.addEventListener("afterhide", onVisibilityChanged);
762 | control.addEventListener("aftershow", onVisibilityChanged);
763 | }
764 | };
765 | }]);
766 |
767 | exists("GridLayout") && module.directive("winGridLayout", function () {
768 | var api = {
769 | groupHeaderPosition: BINDING_property,
770 | maximumRowsOrColumns: BINDING_property,
771 | orientation: BINDING_property
772 | };
773 | return {
774 | require: "^winListView",
775 | restrict: "E",
776 | replace: true,
777 | template: "",
778 | scope: getScopeForAPI(api),
779 | link: function ($scope, elements, attrs, listView) {
780 | var layout;
781 | var controlBindings = initializeControlBindings($scope, api, null, function () { return layout; })
782 | layout = listView.layout = new WinJS.UI.GridLayout(controlBindings.options);
783 | addDestroyListener($scope, layout, controlBindings.bindings);
784 | return layout;
785 | }
786 | };
787 | });
788 |
789 | exists("ListView") && module.directive("winGroupHeaderTemplate", function () {
790 | return {
791 | require: ["^?winListView"],
792 | restrict: "E",
793 | replace: true,
794 | transclude: true,
795 | compile: compileTemplate("groupHeaderTemplate")
796 | };
797 | });
798 |
799 | exists("Hub") && module.directive("winHub", function () {
800 | var api = {
801 | headerTemplate: BINDING_property,
802 | indexOfFirstVisible: BINDING_readonly_property,
803 | indexOfLastVisible: BINDING_readonly_property,
804 | loadingState: BINDING_readonly_property,
805 | orientation: BINDING_property,
806 | scrollPosition: BINDING_property,
807 | sectionOnScreen: BINDING_property,
808 | sections: BINDING_property,
809 | onContentAnimating: BINDING_event,
810 | onHeaderInvoked: BINDING_event,
811 | onLoadingStateChanged: BINDING_event
812 | };
813 | return {
814 | restrict: "E",
815 | replace: true,
816 | scope: getScopeForAPI(api),
817 | template: "
",
818 | transclude: true,
819 | controller: ['$scope', function ($scope) {
820 | // The children will (may) call back before the Hub is constructed so we queue up the calls to
821 | // addSection and removeSection and execute them later.
822 | $scope.deferredCalls = [];
823 | function deferred(wrapped) {
824 | return function () {
825 | var f = Function.prototype.apply.bind(wrapped, null, arguments);
826 | if ($scope.deferredCalls) {
827 | $scope.deferredCalls.push(f);
828 | } else {
829 | f();
830 | }
831 | }
832 | }
833 | proxy($scope, this, "headerTemplate");
834 | this.addSection = deferred(function (section, index) {
835 | $scope.addSection(section, index);
836 | });
837 | this.removeSection = deferred(function (section) {
838 | $scope.removeSection(section);
839 | });
840 | }],
841 | link: function ($scope, elements) {
842 | var element = elements[0];
843 | // NOTE: the Hub will complain if this is in the DOM when it is constructed so we temporarially remove it.
844 | // It must be in the DOM when repeaters run and hosted under the hub.
845 | var sectionsHost = element.firstElementChild;
846 | sectionsHost.parentNode.removeChild(sectionsHost);
847 | var control = initializeControl($scope, element, WinJS.UI.Hub, api);
848 |
849 | element.appendChild(sectionsHost);
850 | $scope.addSection = function (section, index) {
851 | control.sections.splice(index, 0, section);
852 | };
853 | $scope.removeSection = function (section) {
854 | control.sections.splice(control.sections.indexOf(section), 1);
855 | };
856 | $scope.deferredCalls.forEach(function (f) { f(); });
857 | $scope.deferredCalls = null;
858 | control.addEventListener("loadingstatechanged", function () {
859 | apply($scope, function () {
860 | $scope["loadingState"] = control["loadingState"];
861 | });
862 | });
863 | }
864 | };
865 | });
866 |
867 | exists("HubSection") && module.directive("winHubSection", function () {
868 | var api = {
869 | header: BINDING_property,
870 | isHeaderStatic: BINDING_property
871 | };
872 | return {
873 | restrict: "E",
874 | require: "^winHub",
875 | replace: true,
876 | scope: getScopeForAPI(api),
877 | // NOTE: there is an arbitrary wrapper here .placeholder which is used in scenarios where developers stamp
878 | // out hub sections using ng-repeat. In order to support things like that we need to infer the order
879 | // that the sections are in relative to static sections so we manage them in a .placeholder-holder
880 | // element (see winHub directive above), the placeholder always lives in that thing. The content
881 | // (meaning the real hub section) ends up being owned by the Hub.
882 | template: "
",
1124 | transclude: true,
1125 | controller: ['$scope', function ($scope) {
1126 | // The children will (may) call back before the Pivot is constructed so we queue up the calls to
1127 | // addItem and removeItem and execute them later.
1128 | $scope.deferredCalls = [];
1129 | function deferred(wrapped) {
1130 | return function () {
1131 | var f = Function.prototype.apply.bind(wrapped, null, arguments);
1132 | if ($scope.deferredCalls) {
1133 | $scope.deferredCalls.push(f);
1134 | } else {
1135 | f();
1136 | }
1137 | }
1138 | }
1139 | this.addItem = deferred(function (item, index, addedCallback) {
1140 | $scope.addItem(item, index, addedCallback);
1141 | });
1142 | this.removeItem = deferred(function (item) {
1143 | $scope.removeItem(item);
1144 | });
1145 | }],
1146 | link: function ($scope, elements) {
1147 | var element = elements[0];
1148 | var helperDirectives = getHelperDirectives(element, pivotHelperDirectives);
1149 | // NOTE: the Pivot will complain if this is in the DOM when it is constructed so we temporarially remove it.
1150 | // It must be in the DOM when repeaters run and hosted under the pivot.
1151 | var itemsHost = element.firstElementChild;
1152 | itemsHost.parentNode.removeChild(itemsHost);
1153 | var control = initializeControl($scope, element, WinJS.UI.Pivot, api, helperDirectives);
1154 |
1155 | element.appendChild(itemsHost);
1156 | $scope.addItem = function (item, index, addedCallback) {
1157 | control.items.splice(index, 0, item);
1158 | addedCallback();
1159 | };
1160 | $scope.removeItem = function (item) {
1161 | control.items.splice(control.items.indexOf(item), 1);
1162 | };
1163 | $scope.deferredCalls.forEach(function (f) { f(); });
1164 | $scope.deferredCalls = null;
1165 | }
1166 | };
1167 | });
1168 | exists("Pivot") && pivotHelperDirectives.forEach(function (directive) {
1169 | createHelperDirective("winPivot", directive.directiveName);
1170 | });
1171 |
1172 | exists("PivotItem") && module.directive("winPivotItem", function () {
1173 | var api = {
1174 | header: BINDING_property
1175 | };
1176 | return {
1177 | restrict: "E",
1178 | require: "^winPivot",
1179 | replace: true,
1180 | scope: getScopeForAPI(api),
1181 | // NOTE: there is an arbitrary wrapper here .placeholder which is used in scenarios where developers stamp
1182 | // out pivot sections using ng-repeat. In order to support things like that we need to infer the order
1183 | // that the sections are in relative to static sections so we manage them in a .placeholder-holder
1184 | // element (see winPivot directive above), the placeholder always lives in that thing. The content
1185 | // (meaning the real pivot section) ends up being owned by the Hub.
1186 | template: "
",
1187 | transclude: true,
1188 | link: function ($scope, elements, attrs, pivot) {
1189 | var placeholder = elements[0],
1190 | element = placeholder.firstElementChild;
1191 |
1192 | // PivotItems try to communicate with the Pivot control they're instantiated into. This is okay when the Pivot hasn't yet been constructed,
1193 | // but if it has been constructed this will cause problems inside of the Pivot, because the PivotItem will try to set its header in the Pivot
1194 | // before the Pivot has been made aware of its existence via this wrapper's addItem implementation.
1195 | // Ideally we would handle this by removing the PivotItem temporarily from the DOM and adding it in post-initialization, but if we do that
1196 | // we'll cause problems with other WinJS controls that may be hosted in the PivotItem. To solve this problem without doing DOM manipulation,
1197 | // we'll break the PivotItem initialization up into two stages: We will construct the PivotItem manually without any options and allow that blank
1198 | // PivotItem to be processed by its parent Pivot. Once that processing is done and addItem is completed, we'll complete the initialization by
1199 | // setting the PivotItem's options
1200 | removeDuplicateAttributes(element, api);
1201 | var control = initializeControl($scope, element, WinJS.UI.PivotItem, {}, {});
1202 |
1203 | pivot.addItem(control, Array.prototype.indexOf.call(placeholder.parentNode.children, placeholder), function () {
1204 | var controlDetails = initializeControlBindings($scope, api, element, function () { return control; });
1205 |
1206 | WinJS.UI.setOptions(control, controlDetails.options);
1207 | addDestroyListener($scope, control, controlDetails.bindings, function () {
1208 | pivot.removeItem(control);
1209 | });
1210 |
1211 | });
1212 | }
1213 | };
1214 | });
1215 |
1216 | exists("Rating") && module.directive("winRating", function () {
1217 | var api = {
1218 | averageRating: BINDING_property,
1219 | disabled: BINDING_property,
1220 | enableClear: BINDING_property,
1221 | maxRating: BINDING_property,
1222 | tooltipStrings: BINDING_property,
1223 | userRating: BINDING_property,
1224 | onCancel: BINDING_event,
1225 | onChange: BINDING_event,
1226 | onPreviewChange: BINDING_event
1227 | };
1228 | return {
1229 | restrict: "E",
1230 | replace: true,
1231 | scope: getScopeForAPI(api),
1232 | template: "",
1233 | link: function ($scope, elements) {
1234 | var control = initializeControl($scope, elements[0], WinJS.UI.Rating, api);
1235 |
1236 | control.addEventListener("change", function () {
1237 | apply($scope, function () {
1238 | $scope["userRating"] = control["userRating"];
1239 | });
1240 | });
1241 | }
1242 | };
1243 | });
1244 |
1245 | exists("SectionHeaderTemplate") && module.directive("winSectionHeaderTemplate", function () {
1246 | return {
1247 | require: ["^?winHub"],
1248 | restrict: "E",
1249 | replace: true,
1250 | transclude: true,
1251 | compile: compileTemplate("headerTemplate")
1252 | };
1253 | });
1254 |
1255 | exists("SemanticZoom") && module.directive("winSemanticZoom", function () {
1256 | var api = {
1257 | enableButton: BINDING_property,
1258 | locked: BINDING_property,
1259 | zoomedOut: BINDING_property,
1260 | zoomFactor: BINDING_property,
1261 | onZoomChanged: BINDING_event
1262 | };
1263 | return {
1264 | restrict: "E",
1265 | replace: true,
1266 | scope: getScopeForAPI(api),
1267 | template: "",
1268 | transclude: true,
1269 | link: function ($scope, elements) {
1270 | initializeControl($scope, elements[0], WinJS.UI.SemanticZoom, api);
1271 |
1272 | }
1273 | };
1274 | });
1275 |
1276 | exists("SplitView") && module.directive("winSplitView", ['$parse', function ($parse) {
1277 | var api = {
1278 | closedDisplayMode: BINDING_property,
1279 | openedDisplayMode: BINDING_property,
1280 | paneOpened: BINDING_property,
1281 | panePlacement: BINDING_property,
1282 | onBeforeOpen: BINDING_event,
1283 | onAfterOpen: BINDING_event,
1284 | onBeforeClose: BINDING_event,
1285 | onAfterClose: BINDING_event
1286 | };
1287 | return {
1288 | restrict: "E",
1289 | replace: true,
1290 | scope: getScopeForAPI(api),
1291 | template: "",
1292 | transclude: true,
1293 | link: function ($scope, elements, attrs) {
1294 | var element = elements[0],
1295 | paneElement,
1296 | contentElements = [];
1297 | var children = element.children;
1298 | while (element.firstElementChild) {
1299 | var currentElement = element.firstElementChild;
1300 | element.removeChild(currentElement);
1301 | if (currentElement.classList.contains("win-split-view-pane")) {
1302 | currentElement.classList.remove("win-split-view-pane");
1303 | if (!paneElement) {
1304 | paneElement = currentElement;
1305 | }
1306 | } else if (currentElement.classList.contains("win-split-view-content")) {
1307 | currentElement.classList.remove("win-split-view-content");
1308 | contentElements.push(currentElement);
1309 | }
1310 | }
1311 |
1312 | var control = initializeControl($scope, element, WinJS.UI.SplitView, api);
1313 |
1314 | if (paneElement) {
1315 | control.paneElement.appendChild(paneElement);
1316 | }
1317 | for (var i = 0; i < contentElements.length; i++) {
1318 | control.contentElement.appendChild(contentElements[i]);
1319 | }
1320 |
1321 | function onVisibilityChanged() {
1322 | apply($scope, function () {
1323 | $scope["paneOpened"] = control["paneOpened"];
1324 | });
1325 | }
1326 |
1327 | control.addEventListener("afteropen", onVisibilityChanged);
1328 | control.addEventListener("afterclose", onVisibilityChanged);
1329 | }
1330 | };
1331 | }]);
1332 |
1333 | exists("SplitView") && module.directive("winSplitViewPane", function () {
1334 | return {
1335 | require: "^winSplitView",
1336 | restrict: "E",
1337 | replace: true,
1338 | transclude: true,
1339 | template: ""
1340 | };
1341 | });
1342 |
1343 | exists("SplitView") && module.directive("winSplitViewContent", function () {
1344 | return {
1345 | require: "^winSplitView",
1346 | restrict: "E",
1347 | replace: true,
1348 | transclude: true,
1349 | template: ""
1350 | };
1351 | });
1352 |
1353 | exists("SplitViewPaneToggle") && module.directive("winSplitViewPaneToggle", function () {
1354 | var api = {
1355 | splitView: BINDING_property,
1356 | onInvoked: BINDING_event,
1357 | };
1358 | return {
1359 | restrict: "E",
1360 | replace: true,
1361 | scope: getScopeForAPI(api),
1362 | template: "",
1363 | transclude: true,
1364 | link: function ($scope, elements) {
1365 | initializeControl($scope, elements[0], WinJS.UI.SplitViewPaneToggle, api);
1366 | }
1367 | };
1368 | });
1369 |
1370 | exists("SplitViewCommand") && module.directive("winSplitViewCommand", function () {
1371 | var api = {
1372 | icon: BINDING_property,
1373 | label: BINDING_property,
1374 | tooltip: BINDING_property,
1375 | onInvoked: BINDING_event,
1376 | };
1377 | return {
1378 | restrict: "E",
1379 | replace: true,
1380 | scope: getScopeForAPI(api),
1381 | template: "",
1382 | transclude: true,
1383 | link: function ($scope, elements) {
1384 | initializeControl($scope, elements[0], WinJS.UI.SplitViewCommand, api);
1385 | }
1386 | };
1387 | });
1388 |
1389 | exists("TimePicker") && module.directive("winTimePicker", function () {
1390 | var api = {
1391 | clock: BINDING_property,
1392 | current: BINDING_property,
1393 | disabled: BINDING_property,
1394 | hourPattern: BINDING_property,
1395 | minuteIncrement: BINDING_property,
1396 | minutePattern: BINDING_property,
1397 | periodPattern: BINDING_property,
1398 | onChange: BINDING_event
1399 | };
1400 | return {
1401 | restrict: "E",
1402 | replace: true,
1403 | scope: getScopeForAPI(api),
1404 | template: "",
1405 | link: function ($scope, elements) {
1406 | var control = initializeControl($scope, elements[0], WinJS.UI.TimePicker, api);
1407 |
1408 | control.addEventListener("change", function () {
1409 | apply($scope, function () {
1410 | $scope["current"] = control["current"];
1411 | });
1412 | });
1413 | }
1414 | };
1415 | });
1416 |
1417 | exists("ToggleSwitch") && module.directive("winToggleSwitch", function () {
1418 | var api = {
1419 | checked: BINDING_property,
1420 | disabled: BINDING_property,
1421 | labelOff: BINDING_property,
1422 | labelOn: BINDING_property,
1423 | title: BINDING_property,
1424 | onChange: BINDING_event
1425 | };
1426 | return {
1427 | restrict: "E",
1428 | replace: true,
1429 | scope: getScopeForAPI(api),
1430 | template: "",
1431 | link: function ($scope, elements) {
1432 | var control = initializeControl($scope, elements[0], WinJS.UI.ToggleSwitch, api);
1433 |
1434 | control.addEventListener("change", function () {
1435 | apply($scope, function () {
1436 | $scope["checked"] = control["checked"];
1437 | });
1438 | });
1439 | }
1440 | };
1441 | });
1442 |
1443 | exists("ToolBar") && module.directive("winToolBar", function () {
1444 | var api = {
1445 | closedDisplayMode: BINDING_property,
1446 | data: BINDING_property,
1447 | opened: BINDING_property,
1448 | onAfterClose: BINDING_event,
1449 | onAfterOpen: BINDING_event,
1450 | onBeforeClose: BINDING_event,
1451 | onBeforeOpen: BINDING_event
1452 | };
1453 | return {
1454 | restrict: "E",
1455 | replace: true,
1456 | scope: getScopeForAPI(api),
1457 | template: "",
1458 | transclude: true,
1459 | link: function ($scope, elements, attrs) {
1460 | var control = initializeControl($scope, elements[0], WinJS.UI.ToolBar, api);
1461 |
1462 | function onVisibilityChanged() {
1463 | apply($scope, function () {
1464 | $scope["opened"] = control["opened"];
1465 | });
1466 | }
1467 |
1468 | control.addEventListener("afteropen", onVisibilityChanged);
1469 | control.addEventListener("afterclose", onVisibilityChanged);
1470 | }
1471 | };
1472 | });
1473 |
1474 | exists("ToolBar") && module.directive("winToolBarCommand", function () {
1475 | var api = {
1476 | disabled: BINDING_property,
1477 | extraClass: BINDING_property,
1478 | firstElementFocus: BINDING_property,
1479 | flyout: BINDING_property,
1480 | hidden: BINDING_property,
1481 | icon: BINDING_property,
1482 | id: BINDING_property,
1483 | label: BINDING_property,
1484 | lastElementFocus: BINDING_property,
1485 | priority: BINDING_property,
1486 | section: BINDING_property,
1487 | selected: BINDING_property,
1488 | tooltip: BINDING_property,
1489 | type: BINDING_property,
1490 | onClick: BINDING_event
1491 | };
1492 | return {
1493 | restrict: "E",
1494 | replace: true,
1495 | scope: getScopeForAPI(api),
1496 | template: "",
1497 | transclude: true,
1498 | link: function ($scope, elements) {
1499 | initializeControl($scope, elements[0], WinJS.UI.Command, api);
1500 | }
1501 | };
1502 | });
1503 |
1504 | exists("ToolBar") && module.directive("winToolBarSeparator", function () {
1505 | var api = {
1506 | disabled: BINDING_property,
1507 | extraClass: BINDING_property,
1508 | firstElementFocus: BINDING_property,
1509 | flyout: BINDING_property,
1510 | hidden: BINDING_property,
1511 | icon: BINDING_property,
1512 | id: BINDING_property,
1513 | label: BINDING_property,
1514 | lastElementFocus: BINDING_property,
1515 | priority: BINDING_property,
1516 | section: BINDING_property,
1517 | selected: BINDING_property,
1518 | tooltip: BINDING_property,
1519 | type: BINDING_property,
1520 | onClick: BINDING_event
1521 | };
1522 | return {
1523 | restrict: "E",
1524 | replace: true,
1525 | scope: getScopeForAPI(api),
1526 | template: "",
1527 | transclude: true,
1528 | link: function ($scope, elements) {
1529 | initializeControl($scope, elements[0], WinJS.UI.Command, api, { type: "separator" });
1530 | }
1531 | };
1532 | });
1533 |
1534 | exists("ToolBar") && module.directive("winToolBarContent", function () {
1535 | var api = {
1536 | disabled: BINDING_property,
1537 | extraClass: BINDING_property,
1538 | firstElementFocus: BINDING_property,
1539 | flyout: BINDING_property,
1540 | hidden: BINDING_property,
1541 | icon: BINDING_property,
1542 | id: BINDING_property,
1543 | label: BINDING_property,
1544 | lastElementFocus: BINDING_property,
1545 | priority: BINDING_property,
1546 | section: BINDING_property,
1547 | selected: BINDING_property,
1548 | tooltip: BINDING_property,
1549 | type: BINDING_property,
1550 | onClick: BINDING_event
1551 | };
1552 | return {
1553 | restrict: "E",
1554 | replace: true,
1555 | scope: getScopeForAPI(api),
1556 | template: "",
1557 | transclude: true,
1558 | link: function ($scope, elements) {
1559 | initializeControl($scope, elements[0], WinJS.UI.Command, api, { type: "content" });
1560 | }
1561 | };
1562 | });
1563 |
1564 | exists("Tooltip") && module.directive("winTooltip", function () {
1565 | var api = {
1566 | contentElement: BINDING_property,
1567 | extraClass: BINDING_property,
1568 | innerHTML: BINDING_property,
1569 | infotip: BINDING_property,
1570 | placement: BINDING_property,
1571 | onBeforeClose: BINDING_event,
1572 | onBeforeOpen: BINDING_event,
1573 | onClosed: BINDING_event,
1574 | onOpened: BINDING_event
1575 | };
1576 | return {
1577 | restrict: "E",
1578 | replace: true,
1579 | scope: getScopeForAPI(api),
1580 | template: "",
1581 | transclude: true,
1582 | controller: ['$scope', function ($scope) {
1583 | proxy($scope, this, "contentElement");
1584 | }],
1585 | link: function ($scope, elements, attrs) {
1586 | initializeControl($scope, elements[0], WinJS.UI.Tooltip, api);
1587 | }
1588 | };
1589 | });
1590 |
1591 | // Tooltop is a little odd because you have to be able to specify both the element
1592 | // which has a tooltip (the content) and the tooltip's content itself. We specify
1593 | // a special directive which represents the latter.
1594 | exists("Tooltip") && module.directive("winTooltipContent", function () {
1595 | return {
1596 | require: "^winTooltip",
1597 | restrict: "E",
1598 | replace: true,
1599 | transclude: true,
1600 | template: "\
1601 |
\
1602 | \
1603 |
",
1604 | link: function ($scope, elements, attrs, tooltip) {
1605 | tooltip.contentElement = elements[0].firstElementChild;
1606 | }
1607 | };
1608 | });
1609 |
1610 | // Surface winControl property as win-control directive.
1611 | // Keep priority set to a higher value than others (default is 0) as 'link' ie. postLink functions run highest priority last.
1612 | module.directive("winControl", ['$parse', function ($parse) {
1613 | return {
1614 | restrict: "A",
1615 | priority: 1,
1616 | link: function ($scope, element, attrs) {
1617 | if (attrs.winControl) {
1618 | $parse(attrs.winControl).assign($scope, element[0].winControl);
1619 | }
1620 | }
1621 | };
1622 | }]);
1623 |
1624 | }(this));
1625 |
--------------------------------------------------------------------------------
/karma.config.js:
--------------------------------------------------------------------------------
1 | // Karma configuration
2 | // Generated on Thu Dec 04 2014 11:26:12 GMT-0800 (Pacific Standard Time)
3 |
4 | module.exports = function (config) {
5 | config.set({
6 |
7 | // base path, that will be used to resolve files and exclude
8 | basePath: '',
9 |
10 |
11 | // frameworks to use
12 | frameworks: ['jasmine'],
13 |
14 |
15 | // list of files / patterns to load in the browser
16 | files: [
17 | 'node_modules/winjs/js/base.js',
18 | 'node_modules/winjs/js/ui.js',
19 | 'node_modules/winjs/css/ui-dark.css',
20 | 'node_modules/angular/angular.js',
21 | 'node_modules/angular-mocks/angular-mocks.js',
22 | 'js/angular-winjs.js',
23 | 'tests/*.js',
24 | ],
25 |
26 |
27 | // list of files to exclude
28 | exclude: [
29 |
30 | ],
31 |
32 |
33 | // test results reporter to use
34 | // possible values: 'dots', 'progress', 'junit', 'growl', 'coverage'
35 | reporters: ['progress'],
36 |
37 |
38 | // web server port
39 | port: 9876,
40 |
41 |
42 | // enable / disable colors in the output (reporters and logs)
43 | colors: true,
44 |
45 |
46 | // level of logging
47 | // possible values: config.LOG_DISABLE || config.LOG_ERROR || config.LOG_WARN || config.LOG_INFO || config.LOG_DEBUG
48 | logLevel: config.LOG_INFO,
49 |
50 |
51 | // enable / disable watching file and executing tests whenever any file changes
52 | autoWatch: true,
53 |
54 |
55 | // Start these browsers, currently available:
56 | // - Chrome
57 | // - ChromeCanary
58 | // - Firefox
59 | // - Opera (has to be installed with `npm install karma-opera-launcher`)
60 | // - Safari (only Mac; has to be installed with `npm install karma-safari-launcher`)
61 | // - PhantomJS
62 | // - IE (only Windows; has to be installed with `npm install karma-ie-launcher`)
63 | browsers: ['Chrome'],
64 |
65 |
66 | // If browser does not capture in given timeout [ms], kill it
67 | captureTimeout: 60000,
68 |
69 |
70 | // Continuous Integration mode
71 | // if true, it capture browsers, run tests and exit
72 | singleRun: false
73 | });
74 | };
75 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "angular-winjs",
3 | "title": "Angular Wrapper for Windows Library for JavaScript (WinJS)",
4 | "description": "This code is a wrapper which facilitates usage of WinJS UI controls in an Angular application.",
5 | "homepage": "https://github.com/winjs/angular-winjs",
6 | "author": {
7 | "name": "Microsoft Corporation and other contributors",
8 | "url": "https://github.com/winjs/angular-winjs/graphs/contributors"
9 | },
10 | "license": "MIT",
11 | "version": "4.4.0",
12 | "main": "js/angular-winjs.js",
13 | "scripts": {
14 | "test": "karma start karma.config.js"
15 | },
16 | "repository": {
17 | "type": "git",
18 | "url": "https://github.com/winjs/angular-winjs"
19 | },
20 | "keywords": [
21 | "AngularJS",
22 | "WinJS",
23 | "angular",
24 | "windows8",
25 | "windows10"
26 | ],
27 | "licenses": [
28 | {
29 | "type": "MIT",
30 | "url": "https://github.com/winjs/angular-winjs/blob/master/License.txt"
31 | }
32 | ],
33 | "bugs": "https://github.com/winjs/angular-winjs/issues",
34 | "dependencies": {
35 | "angular": "~1.3.13"
36 | },
37 | "devDependencies": {
38 | "angular-mocks": "~1.3.13",
39 | "karma": "~0.10",
40 | "winjs": "4.4.x",
41 | "grunt": "^0.4.5",
42 | "grunt-contrib-clean": "^0.6.0",
43 | "grunt-contrib-compress": "^0.13.0",
44 | "grunt-contrib-copy": "^0.8.0",
45 | "grunt-github-releaser": "^0.1.17",
46 | "grunt-nuget": "^0.1.4"
47 | }
48 | }
49 |
--------------------------------------------------------------------------------
/tasks/check-bom.js:
--------------------------------------------------------------------------------
1 | // Copyright (c) Microsoft Corporation. All Rights Reserved. Licensed under the MIT License. See License.txt in the project root for license information.
2 | (function () {
3 | "use strict";
4 |
5 | module.exports = function (grunt) {
6 |
7 | // Verifies that files begin with a UTF8 BOM. Files without one will not be able to pass the
8 | // Windows App Certification Kit test.
9 |
10 | grunt.registerMultiTask("check-bom", function () {
11 | function checkBom(filePath) {
12 | if (grunt.file.exists(filePath)) {
13 | var content = grunt.file.read(filePath, { encoding: null });
14 | if (content.length < 3 || content[0] !== 0xef || content[1] !== 0xbb || content[2] !== 0xbf) {
15 | grunt.fail.fatal("check-bom File is missing BOM: " + filePath);
16 | }
17 | } else {
18 | grunt.log.warn("check-bom No such file: " + filePath);
19 | }
20 | }
21 |
22 | this.filesSrc.forEach(checkBom);
23 | });
24 |
25 | };
26 | })();
27 |
--------------------------------------------------------------------------------
/tests/AppBar.js:
--------------------------------------------------------------------------------
1 | // Copyright (c) Microsoft Corp. All Rights Reserved. Licensed under the MIT License. See License.txt in the project root for license information.
2 |
3 | describe("AppBar control directive tests", function () {
4 | var testTimeout = 5000;
5 |
6 | var scope,
7 | compile;
8 |
9 | beforeEach(angular.mock.module("winjs"));
10 | beforeEach(angular.mock.inject(function ($rootScope, $compile) {
11 | scope = $rootScope.$new();
12 | compile = $compile;
13 | }));
14 |
15 | function initControl(markup) {
16 | var element = angular.element(markup)[0];
17 | document.body.appendChild(element);
18 | var compiledControl = compile(element)(scope)[0];
19 | scope.$digest();
20 | return compiledControl;
21 | }
22 |
23 | it("should initialize a simple AppBar", function () {
24 | var compiledControl = initControl("");
25 |
26 | expect(compiledControl.winControl).toBeDefined();
27 | expect(compiledControl.winControl instanceof WinJS.UI.AppBar);
28 | expect(compiledControl.className).toContain("win-appbar");
29 | });
30 |
31 | it("should use child AppBarCommands", function () {
32 | var compiledControl = initControl("" +
33 | "" +
34 | "" +
35 | "");
36 |
37 | expect(compiledControl.winControl).toBeDefined();
38 | expect(compiledControl.winControl instanceof WinJS.UI.AppBar);
39 | expect(compiledControl.className).toContain("win-appbar");
40 | expect(compiledControl.querySelectorAll(".win-command").length).toEqual(2);
41 | });
42 |
43 | it("should use the data attribute", function () {
44 | scope.testCommands = new WinJS.Binding.List([
45 | new WinJS.UI.AppBarCommand(null, { label: "TestCommand0" }),
46 | new WinJS.UI.AppBarCommand(null, { label: "TestCommand1" })
47 | ]);
48 | var compiledControl = initControl("");
49 |
50 | var commands = compiledControl.querySelectorAll(".win-command");
51 | expect(commands.length).toEqual(2);
52 | expect(commands[0].querySelector(".win-label").innerHTML).toEqual("TestCommand0");
53 | expect(commands[1].querySelector(".win-label").innerHTML).toEqual("TestCommand1");
54 | });
55 |
56 | it("should use the closedDisplayMode attribute", function () {
57 | var compiledControl = initControl("");
58 | expect(compiledControl.winControl.closedDisplayMode).toEqual("minimal");
59 | });
60 |
61 | it("should use the placement attribute", function () {
62 | var compiledControl = initControl("");
63 | expect(compiledControl.winControl.placement).toEqual("top");
64 | });
65 |
66 | it("should use the opened attribute", function () {
67 | var compiledControl = initControl("");
68 | expect(compiledControl.winControl.opened).toBeTruthy();
69 | });
70 |
71 | it("should use the onopen and onclose event handlers and opened attribute", function () {
72 | var gotBeforeOpenEvent = false,
73 | gotAfterOpenEvent = false,
74 | gotBeforeCloseEvent = false,
75 | gotAfterCloseEvent = false;
76 | scope.beforeOpenEventHandler = function (e) {
77 | gotBeforeOpenEvent = true;
78 | };
79 | scope.afterOpenEventHandler = function (e) {
80 | gotAfterOpenEvent = true;
81 | };
82 | scope.beforeCloseEventHandler = function (e) {
83 | gotBeforeCloseEvent = true;
84 | };
85 | scope.afterCloseEventHandler = function (e) {
86 | gotAfterCloseEvent = true;
87 | };
88 | scope.appbarOpened = false;
89 | var compiledControl = initControl("");
91 | runs(function () {
92 | compiledControl.winControl.open();
93 | });
94 |
95 | waitsFor(function () {
96 | return (gotBeforeOpenEvent && gotAfterOpenEvent);
97 | }, "the AppBar's before+aftershow events", testTimeout);
98 |
99 | runs(function () {
100 | expect(scope.appbarOpened).toBeTruthy();
101 | scope.appbarOpened = false;
102 | scope.$digest();
103 | });
104 |
105 | waitsFor(function () {
106 | return (gotBeforeCloseEvent && gotAfterCloseEvent);
107 | }, "the AppBar's before+afterhide events", testTimeout);
108 | });
109 |
110 | afterEach(function () {
111 | var controls = document.querySelectorAll(".win-appbar");
112 | for (var i = 0; i < controls.length; i++) {
113 | controls[i].parentNode.removeChild(controls[i]);
114 | }
115 | });
116 | });
117 |
--------------------------------------------------------------------------------
/tests/AppBarCommand.js:
--------------------------------------------------------------------------------
1 | // Copyright (c) Microsoft Corp. All Rights Reserved. Licensed under the MIT License. See License.txt in the project root for license information.
2 |
3 | describe("AppBarCommand control directive tests", function () {
4 | var scope,
5 | compile;
6 |
7 | beforeEach(angular.mock.module("winjs"));
8 | beforeEach(angular.mock.inject(function ($rootScope, $compile) {
9 | scope = $rootScope.$new();
10 | compile = $compile;
11 | }));
12 |
13 | function initControl(markup) {
14 | var element = angular.element(markup)[0];
15 | document.body.appendChild(element);
16 | var compiledControl = compile(element)(scope)[0];
17 | scope.$digest();
18 | return compiledControl;
19 | }
20 |
21 | it("should use initialize an AppBar containing two child AppBarCommands", function () {
22 | var compiledControl = initControl("" +
23 | "" +
24 | "" +
25 | "");
26 |
27 | var winControl = compiledControl.winControl;
28 | expect(compiledControl.winControl).toBeDefined();
29 | expect(compiledControl.winControl instanceof WinJS.UI.AppBar);
30 | expect(compiledControl.className).toContain("win-appbar");
31 | expect(compiledControl.querySelectorAll(".win-command").length).toEqual(2);
32 | });
33 |
34 | it("should use the id attribute on AppBarCommands", function () {
35 | var compiledControl = initControl("" +
36 | "" +
37 | "" +
38 | "");
39 |
40 | var commands = compiledControl.querySelectorAll(".win-command");
41 | expect(commands[0].id).toEqual("command1");
42 | expect(commands[1].id).toEqual("command2");
43 | });
44 |
45 | it("should use the label attribute on AppBarCommands", function () {
46 | var compiledControl = initControl("" +
47 | "" +
48 | "" +
49 | "");
50 |
51 | var commands = compiledControl.querySelectorAll(".win-command");
52 | expect(commands[0].querySelector(".win-label").innerHTML).toEqual("command1");
53 | expect(commands[1].querySelector(".win-label").innerHTML).toEqual("command2");
54 | });
55 |
56 | it("should use the disabled attribute on AppBarCommands", function () {
57 | var compiledControl = initControl("" +
58 | "" +
59 | "" +
60 | "");
61 |
62 | var commands = compiledControl.querySelectorAll(".win-command");
63 | expect(commands[0].winControl.disabled).toBeTruthy();
64 | expect(commands[1].winControl.disabled).toBeFalsy();
65 | });
66 |
67 | it("should use the extraClass attribute on AppBarCommands", function () {
68 | var compiledControl = initControl("" +
69 | "" +
70 | "");
71 |
72 | var commands = compiledControl.querySelectorAll(".win-command");
73 | expect(commands[0].className).toContain("extraClass1");
74 | });
75 |
76 | it("should use the section attribute on AppBarCommands", function () {
77 | var compiledControl = initControl("" +
78 | "" +
79 | "" +
80 | "");
81 |
82 | var commands = compiledControl.querySelectorAll(".win-command");
83 | expect(commands[0].winControl.section).toEqual("global");
84 | expect(commands[1].winControl.section).toEqual("selection");
85 | });
86 |
87 | it("should use the hidden attribute on AppBarCommands", function () {
88 | var compiledControl = initControl("" +
89 | "" +
90 | "" +
91 | "");
92 |
93 | var commands = compiledControl.querySelectorAll(".win-command");
94 | expect(commands[0].winControl.hidden).toBeTruthy();
95 | expect(commands[1].winControl.hidden).toBeFalsy();
96 | });
97 |
98 | it("should use the icon attribute on AppBarCommands", function () {
99 | var compiledControl = initControl("" +
100 | "" +
101 | "");
102 |
103 | var commandImage = compiledControl.querySelector(".win-commandimage");
104 | expect(escape(commandImage.innerHTML)).toEqual("%uE109");
105 | });
106 |
107 | it("should use the win-app-bar command types", function () {
108 | var compiledControl = initControl("" +
109 | "" +
110 | "" +
111 | "" +
112 | "");
113 |
114 | var commands = compiledControl.querySelectorAll(".win-command");
115 | expect(commands[0].winControl.type).toEqual("separator");
116 | expect(commands[1].winControl.type).toEqual("content");
117 | expect(commands[2].winControl.type).toEqual("toggle");
118 | });
119 |
120 | it("should use the priority attribute", function () {
121 | var compiledControl = initControl("" +
122 | "" +
123 | "" +
124 | "");
125 |
126 | var commands = compiledControl.querySelectorAll(".win-command");
127 | expect(commands[0].winControl.priority).toEqual(1);
128 | expect(commands[1].winControl.priority).toEqual(2);
129 | });
130 |
131 | it("should use the flyout attribute", function () {
132 | scope.flyout = new WinJS.UI.Flyout();
133 | var compiledControl = initControl("" +
134 | "" +
135 | "");
136 |
137 | var commands = compiledControl.querySelectorAll(".win-command");
138 | expect(commands[0].winControl.flyout).toEqual(scope.flyout);
139 | });
140 |
141 | afterEach(function () {
142 | var controls = document.querySelectorAll(".win-appbar");
143 | for (var i = 0; i < controls.length; i++) {
144 | controls[i].parentNode.removeChild(controls[i]);
145 | }
146 | });
147 | });
148 |
--------------------------------------------------------------------------------
/tests/AutoSuggestBox.js:
--------------------------------------------------------------------------------
1 | // Copyright (c) Microsoft Corp. All Rights Reserved. Licensed under the MIT License. See License.txt in the project root for license information.
2 |
3 | describe("AutoSuggestBox control directive tests", function () {
4 | var scope,
5 | compile;
6 |
7 | beforeEach(angular.mock.module("winjs"));
8 | beforeEach(angular.mock.inject(function ($rootScope, $compile) {
9 | scope = $rootScope.$new();
10 | compile = $compile;
11 | }));
12 |
13 | function initControl(markup) {
14 | var element = angular.element(markup)[0];
15 | document.body.appendChild(element);
16 | var compiledControl = compile(element)(scope)[0];
17 | scope.$digest();
18 | return compiledControl;
19 | }
20 |
21 | it("should initialize a simple autosuggestbox", function () {
22 | var compiledControl = initControl("");
23 |
24 | expect(compiledControl.winControl).toBeDefined();
25 | expect(compiledControl.winControl instanceof WinJS.UI.AutoSuggestBox);
26 | expect(compiledControl.className).toContain("win-autosuggestbox");
27 | });
28 |
29 | it("should use the chooseSuggestionOnEnter attribute", function () {
30 | var compiledControl = initControl("");
31 | expect(compiledControl.winControl.chooseSuggestionOnEnter).toBeTruthy();
32 | });
33 |
34 | it("should use the placeholderText attribute", function () {
35 | var compiledControl = initControl("");
36 | expect(compiledControl.winControl.placeholderText).toEqual("Some Placeholder Text");
37 | });
38 |
39 | it("should use the queryText attribute", function () {
40 | var compiledControl = initControl("");
41 | expect(compiledControl.winControl.queryText).toEqual("Some Query Text");
42 | });
43 |
44 | it("should use the searchHistoryContext attribute", function () {
45 | var compiledControl = initControl("");
46 | expect(compiledControl.winControl.searchHistoryContext).toEqual("searchContext");
47 | });
48 |
49 | it("should use the searchHistoryDisabled attribute", function () {
50 | var compiledControl = initControl("");
51 | expect(compiledControl.winControl.searchHistoryDisabled).toBeTruthy();
52 | });
53 |
54 | afterEach(function () {
55 | var controls = document.querySelectorAll(".win-auto-suggest-box");
56 | for (var i = 0; i < controls.length; i++) {
57 | controls[i].parentNode.removeChild(controls[i]);
58 | }
59 | });
60 | });
61 |
--------------------------------------------------------------------------------
/tests/BackButton.js:
--------------------------------------------------------------------------------
1 | // Copyright (c) Microsoft Corp. All Rights Reserved. Licensed under the MIT License. See License.txt in the project root for license information.
2 |
3 | describe("BackButton control directive tests", function () {
4 | var scope,
5 | compile;
6 |
7 | beforeEach(angular.mock.module("winjs"));
8 | beforeEach(angular.mock.inject(function ($rootScope, $compile) {
9 | scope = $rootScope.$new();
10 | compile = $compile;
11 | }));
12 |
13 | function initControl(markup) {
14 | var element = angular.element(markup)[0];
15 | document.body.appendChild(element);
16 | var compiledControl = compile(element)(scope)[0];
17 | scope.$digest();
18 | return compiledControl;
19 | }
20 |
21 | it("should initialize a simple BackButton", function () {
22 | var compiledControl = initControl("");
23 |
24 | expect(compiledControl.winControl).toBeDefined();
25 | expect(compiledControl.winControl instanceof WinJS.UI.BackButton);
26 | expect(compiledControl.className).toContain("win-navigation-backbutton");
27 | });
28 |
29 | afterEach(function () {
30 | var controls = document.querySelectorAll(".win-navigation-backbutton");
31 | for (var i = 0; i < controls.length; i++) {
32 | controls[i].parentNode.removeChild(controls[i]);
33 | }
34 | });
35 | });
36 |
--------------------------------------------------------------------------------
/tests/ContentDialog.js:
--------------------------------------------------------------------------------
1 | // Copyright (c) Microsoft Corp. All Rights Reserved. Licensed under the MIT License. See License.txt in the project root for license information.
2 |
3 | describe("ContentDialog control directive tests", function () {
4 | var testTimeout = 5000;
5 |
6 | var scope,
7 | compile;
8 |
9 | beforeEach(angular.mock.module("winjs"));
10 | beforeEach(angular.mock.inject(function ($rootScope, $compile) {
11 | scope = $rootScope.$new();
12 | compile = $compile;
13 | }));
14 |
15 | function initControl(markup) {
16 | var element = angular.element(markup)[0];
17 | document.body.appendChild(element);
18 | var compiledControl = compile(element)(scope)[0];
19 | scope.$digest();
20 | return compiledControl;
21 | }
22 |
23 | it("should initialize a simple ContentDialog control", function () {
24 | var compiledControl = initControl("");
25 |
26 | expect(compiledControl.winControl).toBeDefined();
27 | expect(compiledControl.winControl instanceof WinJS.UI.ContentDialog);
28 | expect(compiledControl.className).toContain("win-contentdialog");
29 | });
30 |
31 | it("should use the title attribute", function () {
32 | var compiledControl = initControl("");
33 | expect(compiledControl.winControl.title).toEqual("ContentDialogTitle");
34 | });
35 |
36 | it("should use the primaryCommandText attribute", function () {
37 | var compiledControl = initControl("");
38 | var primaryCommand = compiledControl.querySelector(".win-contentdialog-primarycommand");
39 | expect(primaryCommand.innerHTML).toEqual("PrimaryCommandText");
40 | });
41 |
42 | it("should use the primaryCommandDisabled attribute", function () {
43 | var compiledControl = initControl("");
44 | var primaryCommand = compiledControl.querySelector(".win-contentdialog-primarycommand");
45 | expect(primaryCommand.disabled).toBeTruthy();
46 | });
47 |
48 | it("should use the secondaryCommandText attribute", function () {
49 | var compiledControl = initControl("");
50 | var secondaryCommand = compiledControl.querySelector(".win-contentdialog-secondarycommand");
51 | expect(secondaryCommand.innerHTML).toEqual("SecondaryCommandText");
52 | });
53 |
54 | it("should use the secondaryCommandDisabled attribute", function () {
55 | var compiledControl = initControl("");
56 | var secondaryCommand = compiledControl.querySelector(".win-contentdialog-secondarycommand");
57 | expect(secondaryCommand.disabled).toBeTruthy();
58 | });
59 |
60 | it("should use the onshow and onhide event handlers", function () {
61 | var gotBeforeShowEvent = false,
62 | gotAfterShowEvent = false,
63 | gotBeforeHideEvent = false,
64 | gotAfterHideEvent = false;
65 | scope.beforeShowEventHandler = function (e) {
66 | gotBeforeShowEvent = true;
67 | };
68 | scope.afterShowEventHandler = function (e) {
69 | gotAfterShowEvent = true;
70 | };
71 | scope.beforeHideEventHandler = function (e) {
72 | gotBeforeHideEvent = true;
73 | };
74 | scope.afterHideEventHandler = function (e) {
75 | gotAfterHideEvent = true;
76 | };
77 | scope.dialogHidden = true;
78 | var compiledControl = initControl("");
80 | runs(function () {
81 | compiledControl.winControl.show();
82 | });
83 |
84 | waitsFor(function () {
85 | return (gotBeforeShowEvent && gotAfterShowEvent);
86 | }, "the ContentDialog's before+aftershow events", testTimeout);
87 |
88 | runs(function () {
89 | expect(compiledControl.winControl.hidden).toBeFalsy();
90 | expect(scope.dialogHidden).toBeFalsy();
91 | scope.dialogHidden = true;
92 | scope.$digest();
93 | });
94 |
95 | waitsFor(function () {
96 | return (gotBeforeHideEvent && gotAfterHideEvent);
97 | }, "the ContentDialog's before+afterhide events", testTimeout);
98 |
99 | runs(function () {
100 | expect(compiledControl.winControl.hidden).toBeTruthy();
101 | expect(scope.dialogHidden).toBeTruthy();
102 | });
103 | });
104 |
105 | afterEach(function () {
106 | var controls = document.querySelectorAll(".win-contentdialog");
107 | for (var i = 0; i < controls.length; i++) {
108 | controls[i].parentNode.removeChild(controls[i]);
109 | }
110 | });
111 | });
112 |
--------------------------------------------------------------------------------
/tests/DatePicker.js:
--------------------------------------------------------------------------------
1 | // Copyright (c) Microsoft Corp. All Rights Reserved. Licensed under the MIT License. See License.txt in the project root for license information.
2 |
3 | describe("DatePicker control directive tests", function () {
4 | var scope,
5 | compile;
6 |
7 | beforeEach(angular.mock.module("winjs"));
8 | beforeEach(angular.mock.inject(function ($rootScope, $compile) {
9 | scope = $rootScope.$new();
10 | compile = $compile;
11 | }));
12 |
13 | function initControl(markup) {
14 | var element = angular.element(markup)[0];
15 | document.body.appendChild(element);
16 | var compiledControl = compile(element)(scope)[0];
17 | scope.$digest();
18 | return compiledControl;
19 | }
20 |
21 | it("should initialize a simple DatePicker", function () {
22 | var compiledControl = initControl("");
23 |
24 | expect(compiledControl.winControl).toBeDefined();
25 | expect(compiledControl.winControl instanceof WinJS.UI.DatePicker);
26 | expect(compiledControl.className).toContain("win-datepicker");
27 | });
28 |
29 | it("should use the min and max year attributes", function () {
30 | var compiledControl = initControl("");
31 |
32 | var winControl = compiledControl.winControl;
33 | expect(winControl.minYear).toBe(2013);
34 | expect(winControl.maxYear).toBe(2014);
35 | });
36 |
37 | it("should use the disabled attribute", function () {
38 | var compiledControl = initControl("");
39 |
40 | expect(compiledControl.winControl.disabled).toBeTruthy();
41 | });
42 |
43 | it("should use the current attribute", function () {
44 | scope.testDate = new Date(2013, 3, 7);
45 | var compiledControl = initControl("");
46 |
47 | var winControl = compiledControl.winControl;
48 | expect(winControl.current.getYear()).toBe(113);
49 | expect(winControl.current.getMonth()).toBe(3);
50 | expect(winControl.current.getDate()).toBe(7);
51 | });
52 |
53 | afterEach(function () {
54 | var controls = document.querySelectorAll(".win-datepicker");
55 | for (var i = 0; i < controls.length; i++) {
56 | controls[i].parentNode.removeChild(controls[i]);
57 | }
58 | });
59 | });
60 |
--------------------------------------------------------------------------------
/tests/FlipView.js:
--------------------------------------------------------------------------------
1 | // Copyright (c) Microsoft Corp. All Rights Reserved. Licensed under the MIT License. See License.txt in the project root for license information.
2 |
3 | describe("FlipView control directive tests", function () {
4 | var testTimeout = 5000,
5 | testDataSourceLength = 5;
6 |
7 | var scope,
8 | compile;
9 |
10 | beforeEach(angular.mock.module("winjs"));
11 | beforeEach(angular.mock.inject(function ($rootScope, $compile) {
12 | scope = $rootScope.$new();
13 | compile = $compile;
14 | scope.testDataSource = [];
15 | for (var i = 0; i < testDataSourceLength; i++) {
16 | scope.testDataSource.push({ title: "Item" + i });
17 | }
18 | }));
19 |
20 | function initControl(markup) {
21 | var element = angular.element(markup)[0];
22 | document.body.appendChild(element);
23 | var compiledControl = compile(element)(scope)[0];
24 | scope.$digest();
25 | return compiledControl;
26 | }
27 |
28 | function waitForPageComplete(flipView) {
29 | var pageComplete = false;
30 | flipView.addEventListener("pagecompleted", function (e) {
31 | pageComplete = true;
32 | });
33 |
34 | return function () {
35 | return pageComplete;
36 | };
37 | }
38 |
39 | it("should initialize a simple FlipView", function () {
40 | var compiledControl = initControl("");
41 |
42 | expect(compiledControl.winControl).toBeDefined();
43 | expect(compiledControl.winControl instanceof WinJS.UI.FlipView);
44 | expect(compiledControl.className).toContain("win-flipview");
45 | });
46 |
47 | it("should use an itemDataSource and render content with a win-item-template", function () {
48 | var compiledControl;
49 | var pageCompleted;
50 | runs(function () {
51 | compiledControl = initControl("" +
52 | "" +
53 | "Rendered{{item.data.title}}" +
54 | "" +
55 | "");
56 |
57 | pageCompleted = waitForPageComplete(compiledControl);
58 | });
59 |
60 | waitsFor(function () {
61 | return pageCompleted();
62 | }, "the FlipView's pagecompleted event", testTimeout);
63 |
64 | runs(function () {
65 | var currentPage = compiledControl.winControl._pageManager._currentPage.element;
66 | var boundElement = currentPage.querySelector(".ng-binding");
67 | expect(boundElement.innerHTML).toContain("RenderedItem0");
68 | });
69 | });
70 |
71 | it("should receive a page completed event", function () {
72 | var gotCompletedEvent = false;
73 | scope.completedEventHandler = function (e) {
74 | gotCompletedEvent = true;
75 | };
76 | var compiledControl;
77 | runs(function () {
78 | compiledControl = initControl("");
79 | });
80 |
81 | waitsFor(function () {
82 | return gotCompletedEvent;
83 | }, "the FlipView's pagecompleted event", testTimeout);
84 | });
85 |
86 | it("should receive an on page selected event", function () {
87 | var gotSelectedEvent = false;
88 | scope.selectedEventHandler = function (e) {
89 | gotSelectedEvent = true;
90 | };
91 | var compiledControl;
92 | runs(function () {
93 | compiledControl = initControl("");
94 | });
95 |
96 | waitsFor(function () {
97 | return gotSelectedEvent;
98 | }, "the FlipView's pageselected event", testTimeout);
99 | });
100 |
101 | it("should receive an on page visibility changed event", function () {
102 | var gotChangedEvent = false;
103 | scope.changedEventHandler = function (e) {
104 | gotChangedEvent = true;
105 | };
106 | var compiledControl;
107 | runs(function () {
108 | compiledControl = initControl("");
109 | });
110 |
111 | waitsFor(function () {
112 | return gotChangedEvent;
113 | }, "the FlipView's pagevisibilitychanged event", testTimeout);
114 | });
115 |
116 | it("should receive a datasource count changed event", function () {
117 | var compiledControl;
118 | var pageCompleted;
119 |
120 | runs(function () {
121 | compiledControl = initControl("");
122 | pageCompleted = waitForPageComplete(compiledControl);
123 | });
124 |
125 | waitsFor(function () {
126 | return pageCompleted();
127 | }, "the FlipView's pagecompleted event", testTimeout);
128 |
129 | var gotCountChangedEvent = false;
130 | scope.countChangedEventHandler = function (e) {
131 | gotCountChangedEvent = true;
132 | };
133 |
134 | runs(function () {
135 | scope.testDataSource.push({ title: "NewItem" });
136 | scope.$digest();
137 | });
138 |
139 | waitsFor(function () {
140 | return gotCountChangedEvent;
141 | }, "the FlipView's datasourcecountchanged event", testTimeout);
142 | });
143 |
144 | it("should update currentPage on navigation", function () {
145 | scope.testCurrentPage = 0;
146 | var compiledControl = initControl("");
147 | var pageCompleted = waitForPageComplete(compiledControl);
148 |
149 | waitsFor(function () {
150 | return pageCompleted();
151 | }, "the FlipView's pagecompleted event", testTimeout);
152 |
153 | runs(function () {
154 | compiledControl.winControl.currentPage = 2;
155 | });
156 |
157 | waitsFor(function () {
158 | return (scope.testCurrentPage === 2);
159 | }, "the FlipView to update testCurrentPage", testTimeout);
160 | });
161 |
162 | afterEach(function () {
163 | var controls = document.querySelectorAll(".win-flipview");
164 | for (var i = 0; i < controls.length; i++) {
165 | controls[i].parentNode.removeChild(controls[i]);
166 | }
167 | });
168 | });
169 |
--------------------------------------------------------------------------------
/tests/Flyout.js:
--------------------------------------------------------------------------------
1 | // Copyright (c) Microsoft Corp. All Rights Reserved. Licensed under the MIT License. See License.txt in the project root for license information.
2 |
3 | describe("Flyout control directive tests", function () {
4 | var testTimeout = 5000;
5 |
6 | var scope,
7 | compile;
8 |
9 | beforeEach(angular.mock.module("winjs"));
10 | beforeEach(angular.mock.inject(function ($rootScope, $compile) {
11 | scope = $rootScope.$new();
12 | compile = $compile;
13 | }));
14 |
15 | function initControl(markup) {
16 | var element = angular.element(markup)[0];
17 | document.body.appendChild(element);
18 | var compiledControl = compile(element)(scope)[0];
19 | scope.$digest();
20 | return compiledControl;
21 | }
22 |
23 | it("should initialize a simple Flyout control", function () {
24 | var compiledControl = initControl("");
25 |
26 | expect(compiledControl.winControl).toBeDefined();
27 | expect(compiledControl.winControl instanceof WinJS.UI.Flyout);
28 | expect(compiledControl.className).toContain("win-flyout");
29 | });
30 |
31 | it("should use the alignment attribute", function () {
32 | var compiledControl = initControl("");
33 | expect(compiledControl.winControl.alignment).toEqual("left");
34 | });
35 |
36 | it("should use the disabled attribute", function () {
37 | var compiledControl = initControl("");
38 | expect(compiledControl.winControl.disabled).toBeTruthy();
39 | });
40 |
41 | it("should use the placement attribute", function () {
42 | var compiledControl = initControl("");
43 | expect(compiledControl.winControl.placement).toEqual("right");
44 | });
45 |
46 | it("should use the anchor attribute", function () {
47 | var anchorEl = document.createElement("div");
48 | anchorEl.className = "flyoutTestAnchorElement";
49 | document.body.appendChild(anchorEl);
50 | scope.flyoutAnchor = anchorEl;
51 | var compiledControl = initControl("");
52 | expect(compiledControl.winControl.anchor).toBe(anchorEl);
53 | });
54 |
55 | it("should use the onshow and onhide event handlers and hidden attribute", function () {
56 | var gotBeforeShowEvent = false,
57 | gotAfterShowEvent = false,
58 | gotBeforeHideEvent = false,
59 | gotAfterHideEvent = false;
60 | scope.beforeShowEventHandler = function (e) {
61 | gotBeforeShowEvent = true;
62 | };
63 | scope.afterShowEventHandler = function (e) {
64 | gotAfterShowEvent = true;
65 | };
66 | scope.beforeHideEventHandler = function (e) {
67 | gotBeforeHideEvent = true;
68 | };
69 | scope.afterHideEventHandler = function (e) {
70 | gotAfterHideEvent = true;
71 | };
72 | scope.flyoutHidden = true;
73 | var compiledControl = initControl("");
75 | runs(function () {
76 | compiledControl.winControl.show(document.body);
77 | });
78 |
79 | waitsFor(function () {
80 | return (gotBeforeShowEvent && gotAfterShowEvent);
81 | }, "the Flyout's before+aftershow events", testTimeout);
82 |
83 | runs(function () {
84 | expect(scope.flyoutHidden).toBeFalsy();
85 | scope.flyoutHidden = true;
86 | scope.$digest();
87 | });
88 |
89 | waitsFor(function () {
90 | return (gotBeforeHideEvent && gotAfterHideEvent);
91 | }, "the Flyout's before+afterhide events", testTimeout);
92 |
93 | runs(function () {
94 | expect(scope.flyoutHidden).toBeTruthy();
95 | expect(compiledControl.winControl.hidden).toBeTruthy();
96 | });
97 | });
98 |
99 | afterEach(function () {
100 | var controls = document.querySelectorAll(".win-flyout");
101 | for (var i = 0; i < controls.length; i++) {
102 | controls[i].parentNode.removeChild(controls[i]);
103 | }
104 | var anchors = document.querySelectorAll(".flyoutTestAnchorElement");
105 | for (var i = 0; i < anchors.length; i++) {
106 | anchors[i].parentNode.removeChild(anchors[i]);
107 | }
108 | });
109 | });
110 |
--------------------------------------------------------------------------------
/tests/Hub.js:
--------------------------------------------------------------------------------
1 | // Copyright (c) Microsoft Corp. All Rights Reserved. Licensed under the MIT License. See License.txt in the project root for license information.
2 |
3 | describe("Hub control directive tests", function () {
4 | var testTimeout = 5000;
5 |
6 | var scope,
7 | compile;
8 |
9 | beforeEach(angular.mock.module("winjs"));
10 | beforeEach(angular.mock.inject(function ($rootScope, $compile) {
11 | scope = $rootScope.$new();
12 | compile = $compile;
13 | }));
14 |
15 | function initControl(markup) {
16 | var element = angular.element(markup)[0];
17 | document.body.appendChild(element);
18 | var compiledControl = compile(element)(scope)[0];
19 | scope.$digest();
20 | return compiledControl;
21 | }
22 |
23 | it("should initialize a simple Hub", function () {
24 | var compiledControl = initControl("");
25 |
26 | expect(compiledControl.winControl).toBeDefined();
27 | expect(compiledControl.winControl instanceof WinJS.UI.Hub);
28 | expect(compiledControl.className).toContain("win-hub");
29 | });
30 |
31 | it("should use the orientation attribute", function () {
32 | var compiledControl = initControl("");
33 | expect(compiledControl.winControl.orientation).toEqual("vertical");
34 | });
35 |
36 | afterEach(function () {
37 | var controls = document.querySelectorAll(".win-hub");
38 | for (var i = 0; i < controls.length; i++) {
39 | controls[i].parentNode.removeChild(controls[i]);
40 | }
41 | });
42 | });
43 |
--------------------------------------------------------------------------------
/tests/HubSection.js:
--------------------------------------------------------------------------------
1 | // Copyright (c) Microsoft Corp. All Rights Reserved. Licensed under the MIT License. See License.txt in the project root for license information.
2 |
3 | describe("HubSection control directive tests", function () {
4 | var testTimeout = 5000,
5 | testDataSourceLength = 5;
6 |
7 | var scope,
8 | compile;
9 |
10 | beforeEach(angular.mock.module("winjs"));
11 | beforeEach(angular.mock.inject(function ($rootScope, $compile) {
12 | scope = $rootScope.$new();
13 | compile = $compile;
14 | scope.testDataSource = [];
15 | for (var i = 0; i < testDataSourceLength; i++) {
16 | scope.testDataSource.push({ title: "Item" + i });
17 | }
18 | }));
19 |
20 | function initControl(markup) {
21 | var element = angular.element(markup)[0];
22 | document.body.appendChild(element);
23 | var compiledControl = compile(element)(scope)[0];
24 | scope.$digest();
25 | return compiledControl;
26 | }
27 |
28 | it("should initialize a simple Hub with a single HubSection", function () {
29 | var compiledControl = initControl("" +
30 | "Simple Section" +
31 | "");
32 |
33 | expect(compiledControl.winControl).toBeDefined();
34 | expect(compiledControl.winControl instanceof WinJS.UI.Hub);
35 | expect(compiledControl.className).toContain("win-hub");
36 | expect(compiledControl.querySelectorAll(".win-hub-section").length).toEqual(1);
37 | });
38 |
39 | it("should use the header attribute", function () {
40 | var compiledControl = initControl("" +
41 | "Simple Section" +
42 | "");
43 |
44 | waitsFor(function () {
45 | return (compiledControl.winControl.loadingState === "complete");
46 | }, "the Hub to load", testTimeout);
47 |
48 | runs(function () {
49 | var headers = compiledControl.querySelectorAll(".win-hub-section-header");
50 | expect(headers.length).toEqual(1);
51 | var headerContent = headers[0].querySelectorAll(".win-hub-section-header-content");
52 | expect(headerContent.length).toEqual(1);
53 | expect(headerContent[0].innerHTML).toEqual("SimpleHeader");
54 | });
55 | });
56 |
57 | it("should use the isHeaderStatic attribute", function () {
58 | var compiledControl = initControl("" +
59 | "Simple Section" +
60 | "");
61 | var headers = compiledControl.querySelectorAll(".win-hub-section");
62 | expect(headers.length).toEqual(1);
63 | expect(headers[0].winControl.isHeaderStatic).toBeTruthy();
64 | });
65 |
66 | it("should allow ng-repeat to be used in conjunction with the Hub to create HubSections", function () {
67 | var compiledControl = initControl("" +
68 | "" +
69 | "");
70 |
71 | waitsFor(function () {
72 | return (compiledControl.winControl.loadingState === "complete");
73 | }, "the Hub to load", testTimeout);
74 |
75 | runs(function () {
76 | var headers = compiledControl.querySelectorAll(".win-hub-section-header");
77 | var headerContent = compiledControl.querySelectorAll(".win-hub-section-header-content");
78 | expect(headers.length).toEqual(testDataSourceLength);
79 | expect(headerContent.length).toEqual(testDataSourceLength);
80 | for (var i = 0; i < testDataSourceLength; i++) {
81 | expect(headerContent[i].innerHTML).toEqual("Item" + i);
82 | }
83 | });
84 | });
85 |
86 | afterEach(function () {
87 | var controls = document.querySelectorAll(".win-hub");
88 | for (var i = 0; i < controls.length; i++) {
89 | controls[i].parentNode.removeChild(controls[i]);
90 | }
91 | });
92 | });
93 |
--------------------------------------------------------------------------------
/tests/ItemContainer.js:
--------------------------------------------------------------------------------
1 | // Copyright (c) Microsoft Corp. All Rights Reserved. Licensed under the MIT License. See License.txt in the project root for license information.
2 |
3 | describe("ItemContainer control directive tests", function () {
4 | var scope,
5 | compile;
6 |
7 | beforeEach(angular.mock.module("winjs"));
8 | beforeEach(angular.mock.inject(function ($rootScope, $compile) {
9 | scope = $rootScope.$new();
10 | compile = $compile;
11 | }));
12 |
13 | function initControl(markup) {
14 | var element = angular.element(markup)[0];
15 | document.body.appendChild(element);
16 | var compiledControl = compile(element)(scope)[0];
17 | scope.$digest();
18 | return compiledControl;
19 | }
20 |
21 | it("should initialize a simple ItemContainer", function () {
22 | var compiledControl = initControl("");
23 |
24 | expect(compiledControl.winControl).toBeDefined();
25 | expect(compiledControl.winControl instanceof WinJS.UI.ItemContainer);
26 | expect(compiledControl.className).toContain("win-itemcontainer");
27 | });
28 |
29 | it("should use the draggable attribute", function () {
30 | var compiledControl = initControl("");
31 |
32 | var winControl = compiledControl.winControl;
33 | expect(winControl.draggable).toBeTruthy();
34 | });
35 |
36 | it("should use the selected attribute", function () {
37 | var compiledControl = initControl("");
38 |
39 | var winControl = compiledControl.winControl;
40 | expect(winControl.selected).toBeTruthy();
41 | });
42 |
43 | it("should use the selectionDisabled attribute", function () {
44 | var compiledControl = initControl("");
45 |
46 | var winControl = compiledControl.winControl;
47 | expect(winControl.selectionDisabled).toBeTruthy();
48 | });
49 |
50 | it("should use the tapBehavior attribute", function () {
51 | var compiledControl = initControl("");
52 |
53 | var winControl = compiledControl.winControl;
54 | expect(winControl.tapBehavior).toBe(WinJS.UI.TapBehavior.toggleSelect);
55 | });
56 |
57 | it("should receive selection events", function () {
58 | var gotChangingEvent = false,
59 | gotChangedEvent = false;
60 | scope.changingEventHandler = function (e) {
61 | gotChangingEvent = true;
62 | };
63 | scope.changedEventHandler = function (e) {
64 | gotChangedEvent = true;
65 | };
66 | var compiledControl = initControl("");
67 |
68 | var winControl = compiledControl.winControl;
69 | expect(winControl.selected).toBeFalsy();
70 | expect(gotChangingEvent).toBeFalsy();
71 | expect(gotChangedEvent).toBeFalsy();
72 | winControl.selected = true;
73 | scope.$digest();
74 | expect(winControl.selected).toBeTruthy();
75 | expect(gotChangingEvent).toBeTruthy();
76 | expect(gotChangedEvent).toBeTruthy();
77 | });
78 |
79 | afterEach(function () {
80 | var controls = document.querySelectorAll(".win-itemcontainer");
81 | for (var i = 0; i < controls.length; i++) {
82 | controls[i].parentNode.removeChild(controls[i]);
83 | }
84 | });
85 | });
86 |
--------------------------------------------------------------------------------
/tests/ListView.js:
--------------------------------------------------------------------------------
1 | // Copyright (c) Microsoft Corp. All Rights Reserved. Licensed under the MIT License. See License.txt in the project root for license information.
2 |
3 | describe("ListView control directive tests", function () {
4 | var testTimeout = 5000,
5 | testDataSourceLength = 5;
6 |
7 | var scope,
8 | compile;
9 |
10 | beforeEach(angular.mock.module("winjs"));
11 | beforeEach(angular.mock.inject(function ($rootScope, $compile) {
12 | scope = $rootScope.$new();
13 | compile = $compile;
14 | scope.testDataSource = [];
15 | for (var i = 0; i < testDataSourceLength; i++) {
16 | scope.testDataSource.push({ title: "Item" + i });
17 | }
18 | }));
19 | beforeEach(function () {
20 | WinJS.Utilities._fastAnimations = true;
21 | });
22 |
23 | function initControl(markup) {
24 | var element = angular.element(markup)[0];
25 | document.body.appendChild(element);
26 | var compiledControl = compile(element)(scope)[0];
27 | scope.$digest();
28 | return compiledControl;
29 | }
30 |
31 | function waitForLoadingComplete(listView) {
32 | var loadingComplete = false;
33 | listView.addEventListener("loadingstatechanged", function (e) {
34 | if (listView.loadingState === "complete") {
35 | loadingComplete = true;
36 | }
37 | });
38 |
39 | return function () {
40 | return loadingComplete;
41 | };
42 | }
43 |
44 | it("should initialize a simple ListView", function () {
45 | var compiledControl = initControl("");
46 |
47 | expect(compiledControl.winControl).toBeDefined();
48 | expect(compiledControl.winControl instanceof WinJS.UI.ListView);
49 | expect(compiledControl.className).toContain("win-listview");
50 | });
51 |
52 | it("should use the itemDataSource attribute", function () {
53 | var compiledControl = initControl("");
54 | var loadingComplete = waitForLoadingComplete(compiledControl.winControl);
55 |
56 | waitsFor(function () {
57 | return loadingComplete();
58 | }, "the ListView's loadingStateChanged=complete event", testTimeout);
59 |
60 | runs(function () {
61 | expect(compiledControl.querySelectorAll(".win-container").length).toEqual(testDataSourceLength);
62 | });
63 | });
64 |
65 | it("should use the inline item template", function () {
66 | var compiledControl = initControl("" +
67 | "{{item.data.title}}" +
68 | "");
69 | var loadingComplete = waitForLoadingComplete(compiledControl.winControl);
70 |
71 | waitsFor(function () {
72 | return loadingComplete();
73 | }, "the ListView's loadingStateChanged=complete event", testTimeout);
74 |
75 | runs(function () {
76 | var renderedItems = compiledControl.querySelectorAll(".win-item");
77 | expect(renderedItems.length).toEqual(testDataSourceLength);
78 | for (var i = 0; i < renderedItems.length; i++) {
79 | expect(renderedItems[i].firstElementChild.innerHTML).toEqual(scope.testDataSource[i].title);
80 | }
81 | });
82 | });
83 |
84 | it("should use the inline group header template", function () {
85 | function simpleGroupingFunction(data) {
86 | return data.title;
87 | }
88 | scope.groupedDataSource = new WinJS.Binding.List(scope.testDataSource).createGrouped(simpleGroupingFunction, simpleGroupingFunction);
89 |
90 | var compiledControl = initControl("" +
91 | "{{item.data}}" +
92 | "{{item.data.title}}" +
93 | "");
94 | var loadingComplete = waitForLoadingComplete(compiledControl.winControl);
95 |
96 | waitsFor(function () {
97 | return loadingComplete();
98 | }, "the ListView's loadingStateChanged=complete event", testTimeout);
99 |
100 | runs(function () {
101 | var renderedItems = compiledControl.querySelectorAll(".win-item");
102 | expect(renderedItems.length).toEqual(testDataSourceLength);
103 | for (var i = 0; i < renderedItems.length; i++) {
104 | expect(renderedItems[i].firstElementChild.innerHTML).toEqual(scope.testDataSource[i].title);
105 | }
106 |
107 | var renderedHeaders = compiledControl.querySelectorAll(".win-groupheader");
108 | expect(renderedHeaders.length).toEqual(testDataSourceLength);
109 | for (var i = 0; i < renderedHeaders.length; i++) {
110 | expect(renderedHeaders[i].firstElementChild.innerHTML).toEqual(scope.testDataSource[i].title);
111 | }
112 | });
113 | });
114 |
115 | it("should use the itemsReorderable attribute", function () {
116 | var compiledControl = initControl("");
117 | var loadingComplete = waitForLoadingComplete(compiledControl.winControl);
118 |
119 | waitsFor(function () {
120 | return loadingComplete();
121 | }, "the ListView's loadingStateChanged=complete event", testTimeout);
122 |
123 | runs(function () {
124 | expect(compiledControl.winControl.itemsReorderable).toBeTruthy();
125 | var itemBoxes = compiledControl.querySelectorAll(".win-itembox");
126 | for (var i = 0; i < itemBoxes.length; i++) {
127 | expect(itemBoxes[i].draggable).toBeTruthy();
128 | }
129 | });
130 | });
131 |
132 | it("should use the itemsDraggable attribute", function () {
133 | var compiledControl = initControl("");
134 | var loadingComplete = waitForLoadingComplete(compiledControl.winControl);
135 |
136 | waitsFor(function () {
137 | return loadingComplete();
138 | }, "the ListView's loadingStateChanged=complete event", testTimeout);
139 |
140 | runs(function () {
141 | expect(compiledControl.winControl.itemsDraggable).toBeTruthy();
142 | var itemBoxes = compiledControl.querySelectorAll(".win-itembox");
143 | for (var i = 0; i < itemBoxes.length; i++) {
144 | expect(itemBoxes[i].draggable).toBeTruthy();
145 | }
146 | });
147 | });
148 |
149 | it("should use the loadingStateChanged event handler", function () {
150 | var expectedEventsInOrder = ["itemsLoading", "viewPortLoaded", "itemsLoaded", "complete"],
151 | currentEvent = 0;
152 | scope.loadingStateChangedHandler = function (e) {
153 | expect(e.srcElement.winControl.loadingState).toEqual(expectedEventsInOrder[currentEvent++]);
154 | };
155 | var compiledControl = initControl("" +
156 | "{{item.data.title}}" +
157 | "");
158 | waitsFor(function () {
159 | return (currentEvent === expectedEventsInOrder.length);
160 | }, "the ListView's loadingStateChanged events", testTimeout);
161 | });
162 |
163 | it("should use the maxDeferredItemCleanup attribute", function () {
164 | var compiledControl = initControl("");
165 | expect(compiledControl.winControl.maxDeferredItemCleanup).toEqual(10);
166 | });
167 |
168 | it("should use the maxLeadingPages attribute", function () {
169 | var compiledControl = initControl("");
170 | expect(compiledControl.winControl.maxLeadingPages).toEqual(7);
171 | });
172 |
173 | it("should use the maxTrailingPages attribute", function () {
174 | var compiledControl = initControl("");
175 | expect(compiledControl.winControl.maxTrailingPages).toEqual(7);
176 | });
177 |
178 | it("should use the currentItem attribute", function () {
179 | scope.testCurrentItem = {
180 | index: 2
181 | };
182 | var compiledControl = initControl("");
183 | expect(compiledControl.winControl.currentItem.index).toEqual(2);
184 | });
185 |
186 | it("should use the tapBehavior attribute", function () {
187 | var compiledControl = initControl("");
188 | expect(compiledControl.winControl.tapBehavior).toEqual("toggleSelect");
189 | });
190 |
191 | it("should use the groupHeaderTapBehavior attribute", function () {
192 | var compiledControl = initControl("");
193 | expect(compiledControl.winControl.groupHeaderTapBehavior).toEqual("none");
194 | });
195 |
196 | it("should use the selectionMode attribute", function () {
197 | var compiledControl = initControl("");
198 | expect(compiledControl.winControl.selectionMode).toEqual("none");
199 | });
200 |
201 | it("should use the layout attribute", function () {
202 | scope.layout = new WinJS.UI.ListLayout();
203 | var compiledControl = initControl("");
204 | var loadingComplete = waitForLoadingComplete(compiledControl.winControl);
205 |
206 | waitsFor(function () {
207 | return loadingComplete();
208 | }, "the ListView's loadingStateChanged=complete event", testTimeout);
209 |
210 | runs(function () {
211 | expect(compiledControl.winControl.layout instanceof WinJS.UI.ListLayout).toBeTruthy();
212 | });
213 | });
214 |
215 | it("should use the onAccessibilityAnnotationComplete event", function () {
216 | var gotEvent = false;
217 | scope.handler = function (e) {
218 | gotEvent = true;
219 | };
220 | var compiledControl = initControl("" +
221 | "{{item.data.title}}" +
222 | "");
223 | waitsFor(function () {
224 | return gotEvent;
225 | }, "the ListView's onAccessibilityAnnotationComplete event", testTimeout);
226 | });
227 |
228 | it("should use the onContentAnimating event", function () {
229 | var gotAnimatingEvent = false;
230 | scope.contentAnimatingEventHandler = function (e) {
231 | expect(e.detail.type).toEqual("entrance");
232 | gotAnimatingEvent = true;
233 | };
234 | var compiledControl = initControl("" +
235 | "{{item.data.title}}" +
236 | "");
237 | waitsFor(function () {
238 | return gotAnimatingEvent;
239 | }, "the ListView's onContentAnimating event", testTimeout);
240 | });
241 |
242 | it("should use the selection attribute", function () {
243 | scope.selection = [];
244 | var compiledControl = initControl("" +
245 | "{{item.data.title}}" +
246 | "");
247 | var loadingComplete = waitForLoadingComplete(compiledControl.winControl);
248 |
249 | waitsFor(function () {
250 | return loadingComplete();
251 | }, "the ListView's loadingStateChanged=complete event", testTimeout);
252 |
253 | runs(function () {
254 | var control = compiledControl.winControl;
255 | expect(control.selection.count()).toEqual(0);
256 | scope.selection.push(2);
257 | scope.$digest();
258 | expect(control.selection.count()).toEqual(1);
259 | expect(control.selection.getIndices()[0]).toEqual(2);
260 | });
261 | });
262 |
263 | it("should apply reorders back to the scope", function () {
264 | var compiledControl = initControl("" +
265 | "{{item.data.title}}" +
266 | "");
267 | var originalDataSource = [];
268 | for (var i = 0; i < testDataSourceLength; i++) {
269 | originalDataSource[i] = scope.testDataSource[i];
270 | }
271 | var loadingComplete = waitForLoadingComplete(compiledControl.winControl);
272 |
273 | waitsFor(function () {
274 | return loadingComplete();
275 | }, "the ListView's loadingStateChanged=complete event", testTimeout);
276 |
277 | runs(function () {
278 | var control = compiledControl.winControl;
279 | control.selection.set([testDataSourceLength - 1]);
280 | control._currentMode()._reorderItems(0, control.selection, false, true, false);
281 | loadingComplete = waitForLoadingComplete(compiledControl.winControl);
282 | });
283 |
284 | waitsFor(function () {
285 | return loadingComplete();
286 | }, "the ListView's loadingStateChanged=complete event after reorder", testTimeout);
287 |
288 | runs(function () {
289 | expect(originalDataSource[testDataSourceLength - 1]).toEqual(scope.testDataSource[0]);
290 | expect(originalDataSource[0]).toEqual(scope.testDataSource[1]);
291 | });
292 | });
293 |
294 | it("should use the header and footer attributes", function () {
295 | scope.headerElement = document.createElement("div");
296 | scope.footerElement = document.createElement("div");
297 | var compiledControl = initControl("" +
298 | "{{item.data.title}}" +
299 | "");
300 | var loadingComplete = waitForLoadingComplete(compiledControl.winControl);
301 |
302 | waitsFor(function () {
303 | return loadingComplete();
304 | }, "the ListView's loadingStateChanged=complete event", testTimeout);
305 |
306 | runs(function () {
307 | var control = compiledControl.winControl;
308 | expect(control.header).toEqual(scope.headerElement);
309 | expect(control.footer).toEqual(scope.footerElement);
310 | });
311 | });
312 |
313 | it("should use an inline header and footer", function () {
314 | var compiledControl = initControl("" +
315 | "HeaderElement" +
316 | "{{item.data.title}}" +
317 | "FooterElement" +
318 | "");
319 | var loadingComplete = waitForLoadingComplete(compiledControl.winControl);
320 |
321 | waitsFor(function () {
322 | return loadingComplete();
323 | }, "the ListView's loadingStateChanged=complete event", testTimeout);
324 |
325 | runs(function () {
326 | var control = compiledControl.winControl;
327 | expect(control.header.firstElementChild.innerHTML).toEqual("HeaderElement");
328 | expect(control.footer.firstElementChild.innerHTML).toEqual("FooterElement");
329 | });
330 | });
331 |
332 | afterEach(function () {
333 | var controls = document.querySelectorAll(".win-listview");
334 | for (var i = 0; i < controls.length; i++) {
335 | controls[i].parentNode.removeChild(controls[i]);
336 | }
337 | WinJS.Utilities._fastAnimations = false;
338 | });
339 | });
340 |
--------------------------------------------------------------------------------
/tests/ListViewLayouts.js:
--------------------------------------------------------------------------------
1 | // Copyright (c) Microsoft Corp. All Rights Reserved. Licensed under the MIT License. See License.txt in the project root for license information.
2 |
3 | describe("ListView Layout control directive tests", function () {
4 | var testTimeout = 5000,
5 | testDatasourceLength = 5;
6 |
7 | var scope,
8 | compile;
9 |
10 | beforeEach(angular.mock.module("winjs"));
11 | beforeEach(angular.mock.inject(function ($rootScope, $compile) {
12 | scope = $rootScope.$new();
13 | compile = $compile;
14 | scope.testDataSource = [];
15 | for (var i = 0; i < testDatasourceLength; i++) {
16 | scope.testDataSource.push({ title: "Item" + i });
17 | }
18 | }));
19 | beforeEach(function () {
20 | WinJS.Utilities._fastAnimations = true;
21 | });
22 |
23 | function initControl(markup) {
24 | var element = angular.element(markup)[0];
25 | document.body.appendChild(element);
26 | var compiledControl = compile(element)(scope)[0];
27 | scope.$digest();
28 | return compiledControl;
29 | }
30 |
31 | function waitForLoadingComplete(listView) {
32 | var loadingComplete = false;
33 | listView.addEventListener("loadingstatechanged", function (e) {
34 | if (listView.loadingState === "complete") {
35 | loadingComplete = true;
36 | }
37 | });
38 |
39 | return function () {
40 | return loadingComplete;
41 | };
42 | }
43 |
44 | it("should use the ListLayout defined inline", function () {
45 | var compiledControl = initControl("" +
46 | "{{item.data.title}}" +
47 | "" +
48 | "");
49 | var loadingComplete = waitForLoadingComplete(compiledControl.winControl);
50 |
51 | waitsFor(function () {
52 | return loadingComplete();
53 | }, "the ListView's loadingStateChanged=complete event", testTimeout);
54 |
55 | runs(function () {
56 | expect(compiledControl.winControl.layout instanceof WinJS.UI.ListLayout).toBeTruthy();
57 | });
58 | });
59 |
60 | it("should use the orientation attribute on the ListLayout element", function () {
61 | var compiledControl = initControl("" +
62 | "{{item.data.title}}" +
63 | "" +
64 | "");
65 | var loadingComplete = waitForLoadingComplete(compiledControl.winControl);
66 |
67 | waitsFor(function () {
68 | return loadingComplete();
69 | }, "the ListView's loadingStateChanged=complete event", testTimeout);
70 |
71 | runs(function () {
72 | expect(compiledControl.winControl.layout.orientation).toEqual("horizontal");
73 | });
74 | });
75 |
76 | it("should use the groupHeaderPosition attribute on the ListLayout element", function () {
77 | var compiledControl = initControl("" +
78 | "{{item.data.title}}" +
79 | "" +
80 | "");
81 | var loadingComplete = waitForLoadingComplete(compiledControl.winControl);
82 |
83 | waitsFor(function () {
84 | return loadingComplete();
85 | }, "the ListView's loadingStateChanged=complete event", testTimeout);
86 |
87 | runs(function () {
88 | expect(compiledControl.winControl.layout.groupHeaderPosition).toEqual("left");
89 | });
90 | });
91 |
92 | it("should use the GridLayout defined inline", function () {
93 | var compiledControl = initControl("" +
94 | "{{item.data.title}}" +
95 | "" +
96 | "");
97 | var loadingComplete = waitForLoadingComplete(compiledControl.winControl);
98 |
99 | waitsFor(function () {
100 | return loadingComplete();
101 | }, "the ListView's loadingStateChanged=complete event", testTimeout);
102 |
103 | runs(function () {
104 | expect(compiledControl.winControl.layout instanceof WinJS.UI.GridLayout).toBeTruthy();
105 | });
106 | });
107 |
108 | it("should use the orientation attribute on the GridLayout element", function () {
109 | var compiledControl = initControl("" +
110 | "{{item.data.title}}" +
111 | "" +
112 | "");
113 | var loadingComplete = waitForLoadingComplete(compiledControl.winControl);
114 |
115 | waitsFor(function () {
116 | return loadingComplete();
117 | }, "the ListView's loadingStateChanged=complete event", testTimeout);
118 |
119 | runs(function () {
120 | expect(compiledControl.winControl.layout.orientation).toEqual("vertical");
121 | });
122 | });
123 |
124 | it("should use the groupHeaderPosition attribute on the GridLayout element", function () {
125 | var compiledControl = initControl("" +
126 | "{{item.data.title}}" +
127 | "" +
128 | "");
129 | var loadingComplete = waitForLoadingComplete(compiledControl.winControl);
130 |
131 | waitsFor(function () {
132 | return loadingComplete();
133 | }, "the ListView's loadingStateChanged=complete event", testTimeout);
134 |
135 | runs(function () {
136 | expect(compiledControl.winControl.layout.groupHeaderPosition).toEqual("left");
137 | });
138 | });
139 |
140 | it("should use the maximumRowsOrColumns attribute on the GridLayout element", function () {
141 | var compiledControl = initControl("" +
142 | "{{item.data.title}}" +
143 | "" +
144 | "");
145 | var loadingComplete = waitForLoadingComplete(compiledControl.winControl);
146 |
147 | waitsFor(function () {
148 | return loadingComplete();
149 | }, "the ListView's loadingStateChanged=complete event", testTimeout);
150 |
151 | runs(function () {
152 | expect(compiledControl.winControl.layout.maximumRowsOrColumns).toEqual(3);
153 | });
154 | });
155 |
156 | afterEach(function () {
157 | var controls = document.querySelectorAll(".win-listview");
158 | for (var i = 0; i < controls.length; i++) {
159 | controls[i].parentNode.removeChild(controls[i]);
160 | }
161 | WinJS.Utilities._fastAnimations = false;
162 | });
163 | });
164 |
--------------------------------------------------------------------------------
/tests/Menu.js:
--------------------------------------------------------------------------------
1 | // Copyright (c) Microsoft Corp. All Rights Reserved. Licensed under the MIT License. See License.txt in the project root for license information.
2 |
3 | describe("Menu control directive tests", function () {
4 | var testTimeout = 5000;
5 |
6 | var scope,
7 | compile;
8 |
9 | beforeEach(angular.mock.module("winjs"));
10 | beforeEach(angular.mock.inject(function ($rootScope, $compile) {
11 | scope = $rootScope.$new();
12 | compile = $compile;
13 | }));
14 |
15 | function initControl(markup) {
16 | var element = angular.element(markup)[0];
17 | document.body.appendChild(element);
18 | var compiledControl = compile(element)(scope)[0];
19 | scope.$digest();
20 | return compiledControl;
21 | }
22 |
23 | it("should initialize a simple Menu", function () {
24 | var compiledControl = initControl("");
25 |
26 | expect(compiledControl.winControl).toBeDefined();
27 | expect(compiledControl.winControl instanceof WinJS.UI.Menu);
28 | expect(compiledControl.className).toContain("win-menu");
29 | });
30 |
31 | it("should use child MenuCommands", function () {
32 | var compiledControl = initControl("" +
33 | "" +
34 | "" +
35 | "");
36 |
37 | expect(compiledControl.winControl).toBeDefined();
38 | expect(compiledControl.winControl instanceof WinJS.UI.Menu);
39 | expect(compiledControl.className).toContain("win-menu");
40 | expect(compiledControl.querySelectorAll(".win-command").length).toEqual(2);
41 | });
42 |
43 | it("should use the alignment attribute", function () {
44 | var compiledControl = initControl("");
45 | expect(compiledControl.winControl.alignment).toEqual("right");
46 | });
47 |
48 | it("should use the disabled attribute", function () {
49 | var compiledControl = initControl("");
50 | expect(compiledControl.winControl.disabled).toBeTruthy();
51 | });
52 |
53 | it("should use the placement attribute", function () {
54 | var compiledControl = initControl("");
55 | expect(compiledControl.winControl.placement).toEqual("top");
56 | });
57 |
58 | it("should use the onshow and onhide event handlers and hidden attribute", function () {
59 | var gotBeforeShowEvent = false,
60 | gotAfterShowEvent = false,
61 | gotBeforeHideEvent = false,
62 | gotAfterHideEvent = false;
63 | scope.beforeShowEventHandler = function (e) {
64 | gotBeforeShowEvent = true;
65 | };
66 | scope.afterShowEventHandler = function (e) {
67 | gotAfterShowEvent = true;
68 | };
69 | scope.beforeHideEventHandler = function (e) {
70 | gotBeforeHideEvent = true;
71 | };
72 | scope.afterHideEventHandler = function (e) {
73 | gotAfterHideEvent = true;
74 | };
75 | scope.menuHidden = true;
76 | var compiledControl = initControl("");
78 | runs(function () {
79 | compiledControl.winControl.show(document.body);
80 | });
81 |
82 | waitsFor(function () {
83 | return (gotBeforeShowEvent && gotAfterShowEvent);
84 | }, "the Menu's before+aftershow events", testTimeout);
85 |
86 | runs(function () {
87 | expect(scope.menuHidden).toBeFalsy();
88 | scope.menuHidden = true;
89 | scope.$digest();
90 | });
91 |
92 | waitsFor(function () {
93 | return (gotBeforeHideEvent && gotAfterHideEvent);
94 | }, "the Menu's before+afterhide events", testTimeout);
95 |
96 | runs(function () {
97 | expect(scope.menuHidden).toBeTruthy();
98 | expect(compiledControl.winControl.hidden).toBeTruthy();
99 | });
100 | });
101 |
102 | afterEach(function () {
103 | var controls = document.querySelectorAll(".win-menu");
104 | for (var i = 0; i < controls.length; i++) {
105 | controls[i].parentNode.removeChild(controls[i]);
106 | }
107 | });
108 | });
109 |
--------------------------------------------------------------------------------
/tests/MenuCommand.js:
--------------------------------------------------------------------------------
1 | // Copyright (c) Microsoft Corp. All Rights Reserved. Licensed under the MIT License. See License.txt in the project root for license information.
2 |
3 | describe("MenuCommand control directive tests", function () {
4 | var scope,
5 | compile;
6 |
7 | beforeEach(angular.mock.module("winjs"));
8 | beforeEach(angular.mock.inject(function ($rootScope, $compile) {
9 | scope = $rootScope.$new();
10 | compile = $compile;
11 | }));
12 |
13 | function initControl(markup) {
14 | var element = angular.element(markup)[0];
15 | document.body.appendChild(element);
16 | var compiledControl = compile(element)(scope)[0];
17 | scope.$digest();
18 | return compiledControl;
19 | }
20 |
21 | it("should use initialize a Menu containing two child MenuCommands", function () {
22 | var compiledControl = initControl("" +
23 | "" +
24 | "" +
25 | "");
26 |
27 | var winControl = compiledControl.winControl;
28 | expect(compiledControl.winControl).toBeDefined();
29 | expect(compiledControl.winControl instanceof WinJS.UI.Menu);
30 | expect(compiledControl.className).toContain("win-menu");
31 | expect(compiledControl.querySelectorAll(".win-command").length).toEqual(2);
32 | });
33 |
34 | it("should use the id attribute on MenuCommands", function () {
35 | var compiledControl = initControl("" +
36 | "" +
37 | "" +
38 | "");
39 |
40 | var commands = compiledControl.querySelectorAll(".win-command");
41 | expect(commands[0].id).toEqual("command1");
42 | expect(commands[1].id).toEqual("command2");
43 | });
44 |
45 | it("should use the label attribute on MenuCommands", function () {
46 | var compiledControl = initControl("" +
47 | "" +
48 | "" +
49 | "");
50 |
51 | var commands = compiledControl.querySelectorAll(".win-command");
52 | expect(commands[0].querySelector(".win-label").innerHTML).toEqual("command1");
53 | expect(commands[1].querySelector(".win-label").innerHTML).toEqual("command2");
54 | });
55 |
56 | it("should use the disabled attribute on MenuCommands", function () {
57 | var compiledControl = initControl("" +
58 | "" +
59 | "" +
60 | "");
61 |
62 | var commands = compiledControl.querySelectorAll(".win-command");
63 | expect(commands[0].winControl.disabled).toBeTruthy();
64 | expect(commands[1].winControl.disabled).toBeFalsy();
65 | });
66 |
67 | it("should use the extraClass attribute on MenuCommands", function () {
68 | var compiledControl = initControl("" +
69 | "" +
70 | "");
71 |
72 | var commands = compiledControl.querySelectorAll(".win-command");
73 | expect(commands[0].className).toContain("extraClass1");
74 | });
75 |
76 | it("should use the section attribute on MenuCommands", function () {
77 | var compiledControl = initControl("" +
78 | "" +
79 | "" +
80 | "");
81 |
82 | var commands = compiledControl.querySelectorAll(".win-command");
83 | expect(commands[0].winControl.section).toEqual("global");
84 | expect(commands[1].winControl.section).toEqual("selection");
85 | });
86 |
87 | it("should use the type attribute on MenuCommands", function () {
88 | var compiledControl = initControl("" +
89 | "" +
90 | "" +
91 | "");
92 |
93 | var commands = compiledControl.querySelectorAll(".win-command");
94 | expect(commands[0].winControl.type).toEqual("button");
95 | expect(commands[1].winControl.type).toEqual("toggle");
96 |
97 | });
98 |
99 | afterEach(function () {
100 | var controls = document.querySelectorAll(".win-menu");
101 | for (var i = 0; i < controls.length; i++) {
102 | controls[i].parentNode.removeChild(controls[i]);
103 | }
104 | });
105 | });
106 |
--------------------------------------------------------------------------------
/tests/Pivot.js:
--------------------------------------------------------------------------------
1 | // Copyright (c) Microsoft Corp. All Rights Reserved. Licensed under the MIT License. See License.txt in the project root for license information.
2 |
3 | describe("Pivot control directive tests", function () {
4 | var testTimeout = 5000,
5 | testDatasourceLength = 5;
6 |
7 | var scope,
8 | compile;
9 |
10 | beforeEach(angular.mock.module("winjs"));
11 | beforeEach(angular.mock.inject(function ($rootScope, $compile) {
12 | scope = $rootScope.$new();
13 | compile = $compile;
14 | }));
15 | beforeEach(function () {
16 | WinJS.Utilities._fastAnimations = true;
17 | });
18 |
19 | function initControl(markup) {
20 | var element = angular.element(markup)[0];
21 | document.body.appendChild(element);
22 | var compiledControl = compile(element)(scope)[0];
23 | scope.$digest();
24 | return compiledControl;
25 | }
26 |
27 | it("should initialize a simple Pivot", function () {
28 | var compiledControl = initControl("");
29 |
30 | expect(compiledControl.winControl).toBeDefined();
31 | expect(compiledControl.winControl instanceof WinJS.UI.Pivot);
32 | expect(compiledControl.className).toContain("win-pivot");
33 | });
34 |
35 | it("should use the locked attribute", function () {
36 | var compiledControl = initControl("");
37 | expect(compiledControl.winControl.locked).toBeTruthy();
38 | });
39 |
40 | it("should use the title attribute", function () {
41 | var compiledControl = initControl("");
42 | expect(compiledControl.winControl.title).toEqual("PivotTitle");
43 | });
44 |
45 | it("should use inline pivot items", function () {
46 | var compiledControl = initControl("" +
47 | "Item1" +
48 | "Item2" +
49 | "");
50 | // The Pivot doesn't have a loadingStateChanged event (or any similar loading complete events).
51 | // We'll use itemanimationend as a signal for loading complete.
52 | var gotItemAnimationEndEvent = false;
53 | compiledControl.addEventListener("itemanimationend", function () {
54 | gotItemAnimationEndEvent = true;
55 | }, false);
56 | waitsFor(function () {
57 | return gotItemAnimationEndEvent;
58 | }, "the Pivot to load", testTimeout);
59 |
60 | runs(function () {
61 | var pivotHeaders = compiledControl.querySelectorAll(".win-pivot-header");
62 | var pivotItemContent = compiledControl.querySelectorAll(".win-pivot-item-content");
63 | expect(pivotHeaders.length).toEqual(2);
64 | expect(pivotItemContent.length).toEqual(2);
65 | expect(pivotHeaders[0].innerHTML).toEqual("Header1");
66 | expect(pivotHeaders[1].innerHTML).toEqual("Header2");
67 | expect(pivotItemContent[0].firstElementChild.innerHTML).toEqual("Item1");
68 | expect(pivotItemContent[1].firstElementChild.innerHTML).toEqual("Item2");
69 | });
70 | });
71 |
72 | it("should use the selectedIndex attribute", function () {
73 | scope.selectedIndex = 0;
74 | var compiledControl = initControl("" +
75 | "Item1" +
76 | "Item2" +
77 | ""),
78 | pivot = compiledControl.winControl;
79 |
80 | var gotItemAnimationEndEvent = false;
81 | compiledControl.addEventListener("itemanimationend", function () {
82 | gotItemAnimationEndEvent = true;
83 | }, false);
84 |
85 | waitsFor(function () {
86 | return gotItemAnimationEndEvent;
87 | }, "the Pivot to load", testTimeout);
88 |
89 | runs(function () {
90 | gotItemAnimationEndEvent = false;
91 | expect(pivot.selectedIndex).toEqual(0);
92 | scope.selectedIndex = 1;
93 | scope.$digest();
94 | });
95 |
96 | waitsFor(function () {
97 | return gotItemAnimationEndEvent;
98 | }, "the Pivot to change pages", testTimeout);
99 |
100 | runs(function () {
101 | expect(pivot.selectedIndex).toEqual(1);
102 | });
103 | });
104 |
105 | it("should use the selectedItem attribute", function () {
106 | scope.selectedItem = null;
107 | var compiledControl = initControl("" +
108 | "Item1" +
109 | "Item2" +
110 | ""),
111 | pivot = compiledControl.winControl;
112 |
113 | var gotItemAnimationEndEvent = false;
114 | compiledControl.addEventListener("itemanimationend", function () {
115 | gotItemAnimationEndEvent = true;
116 | }, false);
117 |
118 | waitsFor(function () {
119 | return gotItemAnimationEndEvent;
120 | }, "the Pivot to load", testTimeout);
121 |
122 | runs(function () {
123 | gotItemAnimationEndEvent = false;
124 | expect(pivot.selectedIndex).toEqual(0);
125 | scope.selectedItem = compiledControl.querySelectorAll(".win-pivot-item")[1].winControl;
126 | scope.$digest();
127 | });
128 |
129 | waitsFor(function () {
130 | return gotItemAnimationEndEvent;
131 | }, "the Pivot to change pages", testTimeout);
132 |
133 | runs(function () {
134 | expect(pivot.selectedIndex).toEqual(1);
135 | });
136 | });
137 |
138 | it("should use the on-item-animation-end event handler", function () {
139 | var gotItemAnimationEndEvent = false;
140 | scope.itemAnimationEndHandler = function (e) {
141 | gotItemAnimationEndEvent = true;
142 | };
143 | var compiledControl = initControl("" +
144 | "Item1" +
145 | "");
146 | waitsFor(function () {
147 | return gotItemAnimationEndEvent;
148 | }, "the Pivot to fire animation events", testTimeout);
149 | });
150 |
151 | it("should use the custom header attributes", function () {
152 | scope.customLeftHeader = document.createElement("div");
153 | scope.customRightHeader = document.createElement("div");
154 | var control = initControl("" +
155 | "Item1" +
156 | "").winControl;
157 |
158 | expect(control.customLeftHeader).toEqual(scope.customLeftHeader);
159 | expect(control.customRightHeader).toEqual(scope.customRightHeader);
160 | });
161 |
162 | it("should use the custom header directives", function () {
163 | var control = initControl("" +
164 | "LeftHeader" +
165 | "Item1" +
166 | "RightHeader" +
167 | "").winControl;
168 |
169 | expect(control.customLeftHeader.firstElementChild.innerHTML).toEqual("LeftHeader");
170 | expect(control.customRightHeader.firstElementChild.innerHTML).toEqual("RightHeader");
171 | });
172 |
173 | it("should render child WinJS controls that need to measure", function () {
174 | var listViewLoaded;
175 | scope.onListViewStateChanged = function (e) {
176 | if (e.currentTarget.winControl && e.currentTarget.winControl.loadingState === "complete") {
177 | listViewLoaded = true;
178 | }
179 | };
180 | scope.childData = [1, 2, 3];
181 | var compiledControl = initControl("" +
182 | "" +
183 | "");
184 |
185 | waitsFor(function () {
186 | return listViewLoaded;
187 | }, "the child ListView to load", testTimeout);
188 |
189 | runs(function () {
190 | expect(compiledControl.querySelectorAll(".win-item").length > 0);
191 | });
192 | });
193 |
194 | it("should let ng-repeat add new pivot items", function () {
195 | scope.items = [
196 | { title: "Item0" },
197 | { title: "Item1" }
198 | ];
199 | var compiledControl = initControl("" +
200 | "" +
201 | "");
202 |
203 | var gotItemAnimationEndEvent = false;
204 | compiledControl.addEventListener("itemanimationend", function () {
205 | gotItemAnimationEndEvent = true;
206 | }, false);
207 | waitsFor(function () {
208 | return gotItemAnimationEndEvent;
209 | }, "the Pivot to load", testTimeout);
210 |
211 | runs(function () {
212 | var pivotHeaders = compiledControl.querySelectorAll(".win-pivot-header");
213 | expect(pivotHeaders.length).toEqual(2);
214 | expect(pivotHeaders[0].innerHTML).toEqual("Item0");
215 | expect(pivotHeaders[1].innerHTML).toEqual("Item1");
216 | scope.items.push({ title: "NewItem" });
217 | scope.$digest();
218 | pivotHeaders = compiledControl.querySelectorAll(".win-pivot-header");
219 | expect(pivotHeaders.length).toEqual(3);
220 | expect(pivotHeaders[0].innerHTML).toEqual("Item0");
221 | expect(pivotHeaders[1].innerHTML).toEqual("Item1");
222 | expect(pivotHeaders[2].innerHTML).toEqual("NewItem");
223 | });
224 | });
225 |
226 | afterEach(function () {
227 | var controls = document.querySelectorAll(".win-pivot");
228 | for (var i = 0; i < controls.length; i++) {
229 | controls[i].parentNode.removeChild(controls[i]);
230 | }
231 | WinJS.Utilities._fastAnimations = false;
232 | });
233 | });
234 |
--------------------------------------------------------------------------------
/tests/Rating.js:
--------------------------------------------------------------------------------
1 | // Copyright (c) Microsoft Corp. All Rights Reserved. Licensed under the MIT License. See License.txt in the project root for license information.
2 |
3 | describe("Rating control directive tests", function () {
4 | var scope,
5 | compile;
6 |
7 | beforeEach(angular.mock.module("winjs"));
8 | beforeEach(angular.mock.inject(function ($rootScope, $compile) {
9 | scope = $rootScope.$new();
10 | compile = $compile;
11 | }));
12 |
13 | function initControl(markup) {
14 | var element = angular.element(markup)[0];
15 | document.body.appendChild(element);
16 | var compiledControl = compile(element)(scope)[0];
17 | scope.$digest();
18 | return compiledControl;
19 | }
20 |
21 | it("should initialize a simple Rating control", function () {
22 | var compiledControl = initControl("");
23 |
24 | expect(compiledControl.winControl).toBeDefined();
25 | expect(compiledControl.winControl instanceof WinJS.UI.Rating);
26 | expect(compiledControl.className).toContain("win-rating");
27 | });
28 |
29 | it("should use rating attributes", function () {
30 | var compiledControl = initControl("");
31 |
32 | var winControl = compiledControl.winControl;
33 | expect(winControl.maxRating).toEqual(10);
34 | expect(winControl.userRating).toEqual(9);
35 | expect(winControl.averageRating).toEqual(3);
36 | });
37 |
38 | it("should use the diabled attribute", function () {
39 | var compiledControl = initControl("");
40 |
41 | expect(compiledControl.winControl.disabled).toBeTruthy();
42 | });
43 |
44 | afterEach(function () {
45 | var controls = document.querySelectorAll(".win-rating");
46 | for (var i = 0; i < controls.length; i++) {
47 | controls[i].parentNode.removeChild(controls[i]);
48 | }
49 | });
50 | });
51 |
--------------------------------------------------------------------------------
/tests/SemanticZoom.js:
--------------------------------------------------------------------------------
1 | // Copyright (c) Microsoft Corp. All Rights Reserved. Licensed under the MIT License. See License.txt in the project root for license information.
2 |
3 | describe("SemanticZoom control directive tests", function () {
4 | var testTimeout = 5000,
5 | testDatasourceLength = 5;
6 |
7 | var scope,
8 | compile;
9 |
10 | beforeEach(angular.mock.module("winjs"));
11 | beforeEach(angular.mock.inject(function ($rootScope, $compile) {
12 | scope = $rootScope.$new();
13 | compile = $compile;
14 | scope.rawData = [];
15 | for (var i = 0; i < testDatasourceLength; i++) {
16 | scope.rawData.push({ title: "Item" + i });
17 | }
18 | function simpleGroupingFunction(data) {
19 | return data.title;
20 | }
21 | scope.zoomedInSource = new WinJS.Binding.List(scope.rawData).createGrouped(simpleGroupingFunction, simpleGroupingFunction);
22 | scope.zoomedOutSource = scope.zoomedInSource.groups;
23 | }));
24 | beforeEach(function () {
25 | WinJS.Utilities._fastAnimations = true;
26 | });
27 |
28 | function initControl(markup) {
29 | var element = angular.element(markup)[0];
30 | document.body.appendChild(element);
31 | var compiledControl = compile(element)(scope)[0];
32 | scope.$digest();
33 | return compiledControl;
34 | }
35 |
36 | it("should initialize a simple SemanticZoom", function () {
37 | var compiledControl = initControl("" +
38 | "" +
39 | "" +
40 | "");
41 |
42 | expect(compiledControl.winControl).toBeDefined();
43 | expect(compiledControl.winControl instanceof WinJS.UI.SemanticZoom);
44 | expect(compiledControl.className).toContain("win-semanticzoom");
45 | });
46 |
47 | it("should use the enableButton attribute", function () {
48 | var compiledControl = initControl("" +
49 | "" +
50 | "" +
51 | "");
52 |
53 | expect(compiledControl.winControl.enableButton).toBeFalsy();
54 | });
55 |
56 | it("should use the zoomFactor attribute", function () {
57 | var compiledControl = initControl("" +
58 | "" +
59 | "" +
60 | "");
61 |
62 | expect(compiledControl.winControl.zoomFactor).toEqual(0.25);
63 | });
64 |
65 | it("should use the onZoomChanged event handler", function () {
66 | var gotZoomChangedEvent = false;
67 | scope.zoomChangedHandler = function (e) {
68 | gotZoomChangedEvent = true;
69 | };
70 | var compiledControl = initControl("" +
71 | "" +
72 | "" +
73 | "");
74 |
75 | compiledControl.winControl.zoomedOut = true;
76 | waitsFor(function () {
77 | return gotZoomChangedEvent;
78 | }, "SemanticZoom's onZoomChanged event")
79 | });
80 |
81 | afterEach(function () {
82 | var controls = document.querySelectorAll(".win-semanticzoom");
83 | for (var i = 0; i < controls.length; i++) {
84 | controls[i].parentNode.removeChild(controls[i]);
85 | }
86 | WinJS.Utilities._fastAnimations = false;
87 | });
88 | });
89 |
--------------------------------------------------------------------------------
/tests/SplitView.js:
--------------------------------------------------------------------------------
1 | // Copyright (c) Microsoft Corp. All Rights Reserved. Licensed under the MIT License. See License.txt in the project root for license information.
2 |
3 | describe("SplitView control directive tests", function () {
4 | var testTimeout = 5000;
5 |
6 | var scope,
7 | compile;
8 |
9 | beforeEach(angular.mock.module("winjs"));
10 | beforeEach(angular.mock.inject(function ($rootScope, $compile) {
11 | scope = $rootScope.$new();
12 | compile = $compile;
13 | }));
14 | beforeEach(function () {
15 | WinJS.Utilities._fastAnimations = true;
16 | });
17 |
18 | function initControl(markup) {
19 | var element = angular.element(markup)[0];
20 | document.body.appendChild(element);
21 | var compiledControl = compile(element)(scope)[0];
22 | scope.$digest();
23 | return compiledControl;
24 | }
25 |
26 | it("should initialize a simple SplitView", function () {
27 | var compiledControl = initControl("");
28 |
29 | expect(compiledControl.winControl).toBeDefined();
30 | expect(compiledControl.winControl instanceof WinJS.UI.SplitView);
31 | expect(compiledControl.className).toContain("win-splitview");
32 | });
33 |
34 | it("should use the closedDisplayMode attribute", function () {
35 | var compiledControl = initControl("");
36 | expect(compiledControl.winControl.closedDisplayMode).toEqual("inline");
37 | });
38 |
39 | it("should use the openedDisplayMode attribute", function () {
40 | var compiledControl = initControl("");
41 | expect(compiledControl.winControl.openedDisplayMode).toEqual("inline");
42 | });
43 |
44 | it("should use the panePlacement attribute", function () {
45 | var compiledControl = initControl("");
46 | expect(compiledControl.winControl.panePlacement).toEqual("top");
47 | });
48 |
49 | it("should use inline content and pane nodes", function () {
50 | var compiledControl = initControl("" +
51 | "" +
52 | "" +
53 | "");
54 |
55 | var splitview = compiledControl.winControl;
56 | expect(splitview.paneElement.querySelectorAll(".paneShouldBeInDom").length).toEqual(1);
57 | expect(splitview.contentElement.querySelectorAll(".contentShouldBeInDom").length).toEqual(1);
58 | });
59 |
60 | it("should use inline content and pane nodes regardless of the order they are defined in", function () {
61 | var compiledControl = initControl("" +
62 | "" +
63 | "" +
64 | "");
65 |
66 | var splitview = compiledControl.winControl;
67 | expect(splitview.paneElement.querySelectorAll(".paneShouldBeInDom").length).toEqual(1);
68 | expect(splitview.contentElement.querySelectorAll(".contentShouldBeInDom").length).toEqual(1);
69 | });
70 |
71 | it("should accept multiple splitview content nodes", function () {
72 | var compiledControl = initControl("" +
73 | "" +
74 | "" +
75 | "" +
76 | "");
77 |
78 | var splitview = compiledControl.winControl;
79 | expect(splitview.contentElement.querySelectorAll(".shouldBeInDom").length).toEqual(3);
80 | expect(splitview.paneElement.querySelectorAll(".shouldBeInDom").length).toEqual(0);
81 | });
82 |
83 | it("should ignore additional inline panes", function () {
84 | var compiledControl = initControl("" +
85 | "" +
86 | "" +
87 | "");
88 | expect(compiledControl.querySelectorAll(".shouldBeInDom").length).toEqual(1);
89 | expect(compiledControl.querySelectorAll(".shouldNotBeInDom").length).toEqual(0);
90 | });
91 |
92 | it("should use the open and close event handlers and paneOpened attribute", function () {
93 | var gotBeforeOpenEvent = false,
94 | gotAfterOpenEvent = false,
95 | gotBeforeCloseEvent = false,
96 | gotAfterCloseEvent = false;
97 | scope.beforeOpenEventHandler = function (e) {
98 | gotBeforeOpenEvent = true;
99 | };
100 | scope.afterOpenEventHandler = function (e) {
101 | gotAfterOpenEvent = true;
102 | };
103 | scope.beforeCloseEventHandler = function (e) {
104 | gotBeforeCloseEvent = true;
105 | };
106 | scope.afterCloseEventHandler = function (e) {
107 | gotAfterCloseEvent = true;
108 | };
109 | scope.paneOpened = false;
110 | var compiledControl = initControl("");
112 |
113 | runs(function () {
114 | compiledControl.winControl.openPane();
115 | });
116 |
117 | waitsFor(function () {
118 | return (gotBeforeOpenEvent && gotAfterOpenEvent);
119 | }, "the SplitView's before+aftershow events", testTimeout);
120 |
121 | runs(function () {
122 | expect(scope.paneOpened).toBeTruthy();
123 | scope.paneOpened = false;
124 | scope.$digest();
125 | });
126 |
127 | waitsFor(function () {
128 | return (gotBeforeCloseEvent && gotAfterCloseEvent);
129 | }, "the SplitView's before+afterhide events", testTimeout);
130 | });
131 |
132 | afterEach(function () {
133 | var controls = document.querySelectorAll(".win-splitview");
134 | for (var i = 0; i < controls.length; i++) {
135 | controls[i].parentNode.removeChild(controls[i]);
136 | }
137 | WinJS.Utilities._fastAnimations = false;
138 | });
139 | });
140 |
--------------------------------------------------------------------------------
/tests/SplitViewCommand.js:
--------------------------------------------------------------------------------
1 | // Copyright (c) Microsoft Corp. All Rights Reserved. Licensed under the MIT License. See License.txt in the project root for license information.
2 |
3 | describe("SplitViewCommand control directive tests", function () {
4 | var scope,
5 | compile;
6 |
7 | beforeEach(angular.mock.module("winjs"));
8 | beforeEach(angular.mock.inject(function ($rootScope, $compile) {
9 | scope = $rootScope.$new();
10 | compile = $compile;
11 | }));
12 |
13 | function initControl(markup) {
14 | var element = angular.element(markup)[0];
15 | document.body.appendChild(element);
16 | var compiledControl = compile(element)(scope)[0];
17 | scope.$digest();
18 | return compiledControl;
19 | }
20 |
21 | it("should initialize a simple SplitViewCommand", function () {
22 | var compiledControl = initControl("");
23 |
24 | expect(compiledControl.winControl).toBeDefined();
25 | expect(compiledControl.winControl instanceof WinJS.UI.SplitViewCommand);
26 | expect(compiledControl.className).toContain("win-splitviewcommand");
27 | });
28 |
29 | it("should use the label attribute", function () {
30 | var compiledControl = initControl("");
31 |
32 | expect(compiledControl.querySelector(".win-splitviewcommand-label").innerHTML).toEqual("add");
33 | });
34 |
35 | it("should use the onInvoked attribute", function () {
36 | var gotInvokedEvent = false;
37 | scope.onInvoked = function () {
38 | gotInvokedEvent = true;
39 | };
40 | var compiledControl = initControl("");
41 | var button = compiledControl.querySelector(".win-splitviewcommand-button");
42 | expect(gotInvokedEvent).toBeFalsy();
43 | button.click();
44 | expect(gotInvokedEvent).toBeTruthy();
45 | });
46 |
47 | afterEach(function () {
48 | var controls = document.querySelectorAll(".win-splitviewcommand");
49 | for (var i = 0; i < controls.length; i++) {
50 | controls[i].parentNode.removeChild(controls[i]);
51 | }
52 | });
53 | });
54 |
55 |
--------------------------------------------------------------------------------
/tests/SplitViewPaneToggle.js:
--------------------------------------------------------------------------------
1 | // Copyright (c) Microsoft Corp. All Rights Reserved. Licensed under the MIT License. See License.txt in the project root for license information.
2 |
3 | describe("SplitViewPaneToggle control directive tests", function () {
4 | var scope,
5 | compile;
6 |
7 | beforeEach(angular.mock.module("winjs"));
8 | beforeEach(angular.mock.inject(function ($rootScope, $compile) {
9 | scope = $rootScope.$new();
10 | compile = $compile;
11 | }));
12 |
13 | function initControl(markup) {
14 | var element = angular.element(markup)[0];
15 | document.body.appendChild(element);
16 | var compiledControl = compile(element)(scope)[0];
17 | scope.$digest();
18 | return compiledControl;
19 | }
20 |
21 | it("should initialize a simple SplitViewPaneToggle", function () {
22 | var compiledControl = initControl("");
23 |
24 | expect(compiledControl.winControl).toBeDefined();
25 | expect(compiledControl.winControl instanceof WinJS.UI.SplitViewPaneToggle);
26 | expect(compiledControl.className).toContain("win-splitviewpanetoggle");
27 | });
28 |
29 | it("should use the splitView attribute", function () {
30 | scope.splitView = new WinJS.UI.SplitView().element;
31 | var control = initControl("").winControl;
32 |
33 | expect(control.splitView).toEqual(scope.splitView);
34 | });
35 |
36 | it("should use the onInvoked attribute", function () {
37 | var gotInvokedEvent = false;
38 | scope.onInvoked = function () {
39 | gotInvokedEvent = true;
40 | };
41 | var compiledControl = initControl("");
42 | expect(gotInvokedEvent).toBeFalsy();
43 | compiledControl.click();
44 | expect(gotInvokedEvent).toBeTruthy();
45 | });
46 |
47 | afterEach(function () {
48 | var controls = document.querySelectorAll(".win-splitviewpanetoggle");
49 | for (var i = 0; i < controls.length; i++) {
50 | controls[i].parentNode.removeChild(controls[i]);
51 | }
52 | });
53 | });
54 |
--------------------------------------------------------------------------------
/tests/TimePicker.js:
--------------------------------------------------------------------------------
1 | // Copyright (c) Microsoft Corp. All Rights Reserved. Licensed under the MIT License. See License.txt in the project root for license information.
2 |
3 | describe("TimePicker control directive tests", function () {
4 | var scope,
5 | compile;
6 |
7 | beforeEach(angular.mock.module("winjs"));
8 | beforeEach(angular.mock.inject(function ($rootScope, $compile) {
9 | scope = $rootScope.$new();
10 | compile = $compile;
11 | }));
12 |
13 | function initControl(markup) {
14 | var element = angular.element(markup)[0];
15 | document.body.appendChild(element);
16 | var compiledControl = compile(element)(scope)[0];
17 | scope.$digest();
18 | return compiledControl;
19 | }
20 |
21 | it("should initialize a simple TimePicker", function () {
22 | var compiledControl = initControl("");
23 |
24 | expect(compiledControl.winControl).toBeDefined();
25 | expect(compiledControl.winControl instanceof WinJS.UI.TimePicker);
26 | expect(compiledControl.className).toContain("win-timepicker");
27 | });
28 |
29 | it("should use the clock attribute", function () {
30 | scope.testClock = "24HourClock";
31 | var compiledControl = initControl("");
32 |
33 | expect(compiledControl.winControl.clock).toBe("24HourClock");
34 | });
35 |
36 | it("should use the disabled attribute", function () {
37 | var compiledControl = initControl("");
38 |
39 | expect(compiledControl.winControl.disabled).toBeTruthy();
40 | });
41 |
42 | it("should use the current attribute", function () {
43 | scope.testDate = new Date(2000, 1, 1, 11, 12);
44 | var compiledControl = initControl("");
45 |
46 | var winControl = compiledControl.winControl;
47 | expect(winControl.current.getHours()).toBe(11);
48 | expect(winControl.current.getMinutes()).toBe(12);
49 | });
50 |
51 | it("should use the minuteIncrement attribute", function () {
52 | var compiledControl = initControl("");
53 |
54 | expect(compiledControl.winControl.minuteIncrement).toBe(10);
55 | });
56 |
57 | afterEach(function () {
58 | var controls = document.querySelectorAll(".win-timepicker");
59 | for (var i = 0; i < controls.length; i++) {
60 | controls[i].parentNode.removeChild(controls[i]);
61 | }
62 | });
63 | });
64 |
--------------------------------------------------------------------------------
/tests/ToggleSwitch.js:
--------------------------------------------------------------------------------
1 | // Copyright (c) Microsoft Corp. All Rights Reserved. Licensed under the MIT License. See License.txt in the project root for license information.
2 |
3 | describe("ToggleSwitch control directive tests", function () {
4 | var scope,
5 | compile;
6 |
7 | beforeEach(angular.mock.module("winjs"));
8 | beforeEach(angular.mock.inject(function ($rootScope, $compile) {
9 | scope = $rootScope.$new();
10 | compile = $compile;
11 | }));
12 |
13 | function initControl(markup) {
14 | var element = angular.element(markup)[0];
15 | document.body.appendChild(element);
16 | var compiledControl = compile(element)(scope)[0];
17 | scope.$digest();
18 | return compiledControl;
19 | }
20 |
21 | it("should initialize a simple toggle switch", function () {
22 | var compiledControl = initControl("");
23 |
24 | expect(compiledControl.winControl).toBeDefined();
25 | expect(compiledControl.winControl instanceof WinJS.UI.ToggleSwitch);
26 | expect(compiledControl.className).toContain("win-toggleswitch");
27 | });
28 |
29 | it("should use the checked attribute", function () {
30 | var compiledControl = initControl("");
31 |
32 | var winControl = compiledControl.winControl;
33 | expect(winControl.checked).toBeTruthy();
34 | });
35 |
36 | it("should use label attributes", function () {
37 | var compiledControl = initControl("");
38 |
39 | expect(compiledControl.querySelector(".win-toggleswitch-value-on").innerHTML).toBe("onLabel");
40 | expect(compiledControl.querySelector(".win-toggleswitch-value-off").innerHTML).toBe("offLabel");
41 | });
42 |
43 | it("should use the title attribute", function () {
44 | var compiledControl = initControl("");
45 |
46 | expect(compiledControl.querySelector(".win-toggleswitch-header").innerHTML).toBe("toggleTitle");
47 | });
48 |
49 | it("should use the disabled attribute", function () {
50 | var compiledControl = initControl("");
51 |
52 | expect(compiledControl.winControl.disabled).toBeTruthy();
53 | });
54 |
55 | it("should allow event handlers to be set up in markup", function () {
56 | var eventHandlerCalled = false;
57 | scope.changedEventHandler = function (e) {
58 | eventHandlerCalled = true;
59 | };
60 | scope.isChecked = false;
61 | var compiledControl = initControl("");
62 |
63 | var winControl = compiledControl.winControl;
64 | expect(winControl.checked).toBeFalsy();
65 | scope.isChecked = true;
66 | scope.$digest();
67 | expect(winControl.checked).toBeTruthy();
68 | expect(eventHandlerCalled).toBeTruthy();
69 | });
70 |
71 | afterEach(function () {
72 | var controls = document.querySelectorAll(".win-toggleswitch");
73 | for (var i = 0; i < controls.length; i++) {
74 | controls[i].parentNode.removeChild(controls[i]);
75 | }
76 | });
77 | });
78 |
--------------------------------------------------------------------------------
/tests/ToolBar.js:
--------------------------------------------------------------------------------
1 | // Copyright (c) Microsoft Corp. All Rights Reserved. Licensed under the MIT License. See License.txt in the project root for license information.
2 |
3 | describe("ToolBar control directive tests", function () {
4 | var testTimeout = 5000;
5 |
6 | var scope,
7 | compile;
8 |
9 | beforeEach(angular.mock.module("winjs"));
10 | beforeEach(angular.mock.inject(function ($rootScope, $compile) {
11 | scope = $rootScope.$new();
12 | compile = $compile;
13 | }));
14 |
15 | function initControl(markup) {
16 | var element = angular.element(markup)[0];
17 | document.body.appendChild(element);
18 | var compiledControl = compile(element)(scope)[0];
19 | scope.$digest();
20 | return compiledControl;
21 | }
22 |
23 | it("should initialize a simple ToolBar", function () {
24 | var compiledControl = initControl("");
25 |
26 | expect(compiledControl.winControl).toBeDefined();
27 | expect(compiledControl.winControl instanceof WinJS.UI.ToolBar);
28 | expect(compiledControl.className).toContain("win-toolbar");
29 | });
30 |
31 | it("should use child ToolBarCommands", function () {
32 | var compiledControl = initControl("" +
33 | "" +
34 | "" +
35 | "");
36 |
37 | expect(compiledControl.querySelectorAll(".win-command").length).toEqual(2);
38 | });
39 |
40 | it("should use the closedDisplayMode attribute", function () {
41 | var compiledControl = initControl("");
42 | expect(compiledControl.winControl.closedDisplayMode).toEqual("full");
43 | });
44 |
45 | it("should use the onopen and onclose event handlers and opened attribute", function () {
46 | var gotBeforeOpenEvent = false,
47 | gotAfterOpenEvent = false,
48 | gotBeforeCloseEvent = false,
49 | gotAfterCloseEvent = false;
50 | scope.beforeOpenEventHandler = function (e) {
51 | gotBeforeOpenEvent = true;
52 | };
53 | scope.afterOpenEventHandler = function (e) {
54 | gotAfterOpenEvent = true;
55 | };
56 | scope.beforeCloseEventHandler = function (e) {
57 | gotBeforeCloseEvent = true;
58 | };
59 | scope.afterCloseEventHandler = function (e) {
60 | gotAfterCloseEvent = true;
61 | };
62 | scope.toolbarOpened = false;
63 | var compiledControl = initControl("");
65 | runs(function () {
66 | compiledControl.winControl.open();
67 | });
68 |
69 | waitsFor(function () {
70 | return (gotBeforeOpenEvent && gotAfterOpenEvent);
71 | }, "the ToolBar's before+aftershow events", testTimeout);
72 |
73 | runs(function () {
74 | expect(scope.toolbarOpened).toBeTruthy();
75 | scope.toolbarOpened = false;
76 | scope.$digest();
77 | });
78 |
79 | waitsFor(function () {
80 | return (gotBeforeCloseEvent && gotAfterCloseEvent);
81 | }, "the ToolBar's before+afterhide events", testTimeout);
82 | });
83 |
84 | afterEach(function () {
85 | var controls = document.querySelectorAll(".win-toolbar");
86 | for (var i = 0; i < controls.length; i++) {
87 | controls[i].parentNode.removeChild(controls[i]);
88 | }
89 | });
90 | });
91 |
--------------------------------------------------------------------------------
/tests/ToolBarCommand.js:
--------------------------------------------------------------------------------
1 | // Copyright (c) Microsoft Corp. All Rights Reserved. Licensed under the MIT License. See License.txt in the project root for license information.
2 |
3 | describe("ToolBarCommand control directive tests", function () {
4 | var scope,
5 | compile;
6 |
7 | beforeEach(angular.mock.module("winjs"));
8 | beforeEach(angular.mock.inject(function ($rootScope, $compile) {
9 | scope = $rootScope.$new();
10 | compile = $compile;
11 | }));
12 |
13 | function initControl(markup) {
14 | var element = angular.element(markup)[0];
15 | document.body.appendChild(element);
16 | var compiledControl = compile(element)(scope)[0];
17 | scope.$digest();
18 | return compiledControl;
19 | }
20 |
21 | it("should use initialize a ToolBar containing two child ToolBarCommands", function () {
22 | var compiledControl = initControl("" +
23 | "" +
24 | "" +
25 | "");
26 |
27 | var winControl = compiledControl.winControl;
28 | expect(compiledControl.winControl).toBeDefined();
29 | expect(compiledControl.winControl instanceof WinJS.UI.ToolBar);
30 | expect(compiledControl.className).toContain("win-toolbar");
31 | expect(compiledControl.querySelectorAll(".win-command").length).toEqual(2);
32 | });
33 |
34 | it("should use the id attribute on ToolBarCommands", function () {
35 | var compiledControl = initControl("" +
36 | "" +
37 | "" +
38 | "");
39 |
40 | var commands = compiledControl.querySelectorAll(".win-command");
41 | expect(commands[0].id).toEqual("command1");
42 | expect(commands[1].id).toEqual("command2");
43 | });
44 |
45 | it("should use the label attribute on ToolBarCommands", function () {
46 | var compiledControl = initControl("" +
47 | "" +
48 | "" +
49 | "");
50 |
51 | var commands = compiledControl.querySelectorAll(".win-command");
52 | expect(commands[0].querySelector(".win-label").innerHTML).toEqual("command1");
53 | expect(commands[1].querySelector(".win-label").innerHTML).toEqual("command2");
54 | });
55 |
56 | it("should use the disabled attribute on ToolBarCommands", function () {
57 | var compiledControl = initControl("" +
58 | "" +
59 | "" +
60 | "");
61 |
62 | var commands = compiledControl.querySelectorAll(".win-command");
63 | expect(commands[0].winControl.disabled).toBeTruthy();
64 | expect(commands[1].winControl.disabled).toBeFalsy();
65 | });
66 |
67 | it("should use the extraClass attribute on ToolBarCommands", function () {
68 | var compiledControl = initControl("" +
69 | "" +
70 | "");
71 |
72 | var commands = compiledControl.querySelectorAll(".win-command");
73 | expect(commands[0].className).toContain("extraClass1");
74 | });
75 |
76 | it("should use the section attribute on ToolBarCommands", function () {
77 | var compiledControl = initControl("" +
78 | "" +
79 | "" +
80 | "");
81 |
82 | var commands = compiledControl.querySelectorAll(".win-command");
83 | expect(commands[0].winControl.section).toEqual("global");
84 | expect(commands[1].winControl.section).toEqual("selection");
85 | });
86 |
87 | afterEach(function () {
88 | var controls = document.querySelectorAll(".win-toolbar");
89 | for (var i = 0; i < controls.length; i++) {
90 | controls[i].parentNode.removeChild(controls[i]);
91 | }
92 | });
93 | });
94 |
--------------------------------------------------------------------------------
/tests/Tooltip.js:
--------------------------------------------------------------------------------
1 | // Copyright (c) Microsoft Corp. All Rights Reserved. Licensed under the MIT License. See License.txt in the project root for license information.
2 |
3 | describe("Tooltip control directive tests", function () {
4 | var scope,
5 | compile;
6 |
7 | beforeEach(angular.mock.module("winjs"));
8 | beforeEach(angular.mock.inject(function ($rootScope, $compile) {
9 | scope = $rootScope.$new();
10 | compile = $compile;
11 | }));
12 |
13 | function initControl(markup) {
14 | var element = angular.element(markup)[0];
15 | document.body.appendChild(element);
16 | var compiledControl = compile(element)(scope)[0];
17 | scope.$digest();
18 | return compiledControl;
19 | }
20 |
21 | it("should initialize a simple Tooltip", function () {
22 | var compiledControl = initControl("");
23 |
24 | expect(compiledControl.winControl).toBeDefined();
25 | expect(compiledControl.winControl instanceof WinJS.UI.Tooltip);
26 | compiledControl.parentNode.removeChild(compiledControl);
27 | });
28 |
29 | it("should initialize the infotip attribute", function () {
30 | var compiledControl = initControl("");
31 | expect(compiledControl.winControl.infotip).toBeTruthy();
32 | compiledControl.parentNode.removeChild(compiledControl);
33 | });
34 |
35 | it("should initialize the placement attribute", function () {
36 | var compiledControl = initControl("");
37 | expect(compiledControl.winControl.placement).toEqual("right");
38 | compiledControl.parentNode.removeChild(compiledControl);
39 | });
40 | });
41 |
--------------------------------------------------------------------------------