<% if(icon) { %>
<% } %><%= value %>
--------------------------------------------------------------------------------
/src/templates/default/textarea.ejs:
--------------------------------------------------------------------------------
1 |
<% if(label) { %><% } %>
--------------------------------------------------------------------------------
/src/templates/default/textfield.ejs:
--------------------------------------------------------------------------------
1 |
<% if(label) { %>
<% } %>
--------------------------------------------------------------------------------
/src/templates/default/toast.ejs:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/src/templates/default/toggle.ejs:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/src/templates/default/toggleswitch.ejs:
--------------------------------------------------------------------------------
1 |
2 |
<%= value %>
3 |
4 | <% if(label){%>
5 |
<%= label %>
6 | <% }%>
7 |
8 |
9 | <% if(onLabel){%>
10 |
<%= onLabel %>
11 | <% }%>
12 |
13 | <% if(onLabel){%>
14 |
<%= offLabel %>
15 | <% }%>
16 |
17 | <% if(onLabel){%>
18 |
19 | <% }%>
20 |
21 |
22 |
23 |
24 |
--------------------------------------------------------------------------------
/src/templates/default/toolbar.ejs:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/src/templates/default/view.ejs:
--------------------------------------------------------------------------------
1 |
<%= value %>
--------------------------------------------------------------------------------
/src/themproject.bd.js:
--------------------------------------------------------------------------------
1 | // @echo BANNER
2 |
3 | (function (global, Backbone, _, $) {
4 |
5 | // @include ./_core.js
6 |
7 | })(this, Backbone, _, $);
8 |
--------------------------------------------------------------------------------
/src/themproject.js:
--------------------------------------------------------------------------------
1 | // @echo BANNER
2 |
3 | (function (global, Backbone, _, $) {
4 |
5 | // @include ./_core.js
6 | // @include ./_ui.js
7 |
8 | })(this, Backbone, _, $);
9 |
--------------------------------------------------------------------------------
/src/ui/layouts/bottom-bar-layout.js:
--------------------------------------------------------------------------------
1 | // Copyright (c) 2013 M-Way Solutions GmbH
2 | // http://github.com/mwaylabs/The-M-Project/blob/absinthe/MIT-LICENSE.txt
3 |
4 | M.Themes.registerTemplateForTheme( M.Themes.DEFAULT_THEME, 'bottom-bar-layout', '
' );
5 | /**
6 | *
7 | * @module M.BottomBarLayout
8 | * @type {*}
9 | * @extends M.Layout
10 | */
11 | M.BottomBarLayout = M.Layout.extend({
12 |
13 | _type: 'bottom-bar-layout',
14 |
15 | template: M.Themes.getTemplateByName('bottom-bar-layout')
16 | });
--------------------------------------------------------------------------------
/src/ui/layouts/header-layout.js:
--------------------------------------------------------------------------------
1 | // Copyright (c) 2013 M-Way Solutions GmbH
2 | // http://github.com/mwaylabs/The-M-Project/blob/absinthe/MIT-LICENSE.txt
3 |
4 | M.Themes.registerTemplateForTheme(M.Themes.DEFAULT_THEME, 'header-layout', '');
5 | /**
6 | *
7 | * @module M.HeaderLayout
8 | * @type {*}
9 | * @extends M.Layout
10 | */
11 | M.HeaderLayout = M.Layout.extend({
12 |
13 | _type: 'header-layout',
14 |
15 | template: M.Themes.getTemplateByName('header-layout'),
16 |
17 | applyViews: function( settings ) {
18 |
19 |
20 | var ident = 'header';
21 |
22 | if(!this.childViews[ident] && settings.header){
23 | this.addChildView(ident, settings.header);
24 | }
25 |
26 | if( settings.header && !this._firstRender ) {
27 | this.$el.find('[data-childviews="' + ident + '"]').html('');
28 | this.$el.find('[data-childviews="' + ident + '"]').html(settings.header.render().$el);
29 | }
30 |
31 | return this;
32 | }
33 |
34 | });
--------------------------------------------------------------------------------
/src/ui/layouts/layout.js:
--------------------------------------------------------------------------------
1 | // Copyright (c) 2013 M-Way Solutions GmbH
2 | // http://github.com/mwaylabs/The-M-Project/blob/absinthe/MIT-LICENSE.txt
3 |
4 | /**
5 | *
6 | * @module M.Layout
7 | * @type {*}
8 | * @extends M.View
9 | */
10 | M.Layout = M.View.extend(/** @scope M.Layout.prototype */{
11 |
12 | //el: $(".m-perspective"),
13 |
14 | /**
15 | * The type of this object.
16 | *
17 | * @type String
18 | */
19 | _type: 'M.Layout',
20 |
21 | /**
22 | * This property is used to identify M.Layout and all of its derived object
23 | * as layouts.
24 | *
25 | * @type Boolean
26 | */
27 | isMLayout: YES,
28 |
29 | template: '
',
30 |
31 | childViews: {},
32 |
33 | applyViews: function() {
34 | this._getsVisible();
35 | },
36 |
37 | _attachToDom: function() {
38 | return YES;
39 | },
40 |
41 | setTransition: function( name ) {
42 | M.PageTransitions.setTransition( name );
43 | },
44 |
45 | startTransition: function() {
46 | M.PageTransitions.startTransition();
47 | this._getsVisible();
48 | },
49 |
50 | isAnimating: function() {
51 | return M.PageTransitions.isAnimating();
52 | },
53 |
54 | destroy: function() {
55 | this.$el.remove();
56 | this.$el = null;
57 | this.childViews = null;
58 | M.PageTransitions.reset();
59 | }
60 | });
--------------------------------------------------------------------------------
/src/ui/layouts/switch-header-content.js:
--------------------------------------------------------------------------------
1 | // Copyright (c) 2013 M-Way Solutions GmbH
2 | // http://github.com/mwaylabs/The-M-Project/blob/absinthe/MIT-LICENSE.txt
3 |
4 | (function( scope ) {
5 |
6 | /**
7 | * the switchlayout template
8 | * @type {string}
9 | */
10 | var switchTemplate = M.SwitchLayout.prototype.template;
11 | /**
12 | * the header template
13 | * @type {string}
14 | */
15 | var headerTemplate = M.HeaderLayout.prototype.template;
16 | /**
17 | * add a header to the both content container
18 | * @type {string}
19 | */
20 | var myTemplate = switchTemplate.replace(/m-page-1">/gi, 'm-page-1">' + headerTemplate.replace(/data-childviews="header"/gi, 'data-childviews="content_page1_header"'));
21 | myTemplate = myTemplate.replace(/m-page-2">/gi, 'm-page-2">' + headerTemplate.replace(/data-childviews="header"/gi, 'data-childviews="content_page2_header"'));
22 |
23 | /**
24 | * A Switchlayout with a header and content
25 | * @type {*|Object|void}
26 | */
27 | M.SwitchHeaderContentLayout = M.SwitchLayout.extend({
28 |
29 | _type: 'M.SwitchHeaderContentLayout',
30 |
31 | /**
32 | * the template - a combination of the header and switch template
33 | * @type {string}
34 | */
35 | template: myTemplate,
36 |
37 | cssClass:'switch-header-content-layout',
38 |
39 | /**
40 | * The content gets mapped to the DOM via the Switchlayout. Then map the header to the Layout.
41 | * @param {Object} the views to display
42 | * @returns {SwitchHeaderContentLayout}
43 | */
44 | applyViews: function( settings ) {
45 |
46 | M.SwitchLayout.prototype.applyViews.apply(this, [settings]);
47 |
48 | if(!this.childViews[this._currentPage + '_header'] && settings.header){
49 | this.setChildView(this._currentPage + '_header', settings.header);
50 | }
51 |
52 | if( settings.header && !this._firstRender ) {
53 | this.$el.find('[data-childviews="' + this._currentPage + '_header' + '"]').html('');
54 | this.$el.find('[data-childviews="' + this._currentPage + '_header' + '"]').html(settings.header.render().$el);
55 | }
56 |
57 | return this;
58 | }
59 | });
60 |
61 |
62 | })(this);
--------------------------------------------------------------------------------
/src/ui/layouts/switch-layout.js:
--------------------------------------------------------------------------------
1 | // Copyright (c) 2013 M-Way Solutions GmbH
2 | // http://github.com/mwaylabs/The-M-Project/blob/absinthe/MIT-LICENSE.txt
3 |
4 | M.Themes.registerTemplateForTheme(M.Themes.DEFAULT_THEME, 'switch-layout', '
');
5 | /**
6 | *
7 | * @module M.SwitchLayout
8 | * @type {*}
9 | * @extends M.Layout
10 | */
11 | M.SwitchLayout = M.Layout.extend({
12 |
13 | /**
14 | * The type of the Layout
15 | */
16 | _type: 'M.SwitchLayout',
17 |
18 | /**
19 | * The template of the Layout
20 | */
21 | template: M.Themes.getTemplateByName('switch-layout'),
22 |
23 | /**
24 | * The SwitchLayout has two container to display the content. This attribute determines which of those 2 is active at the moment
25 | */
26 | _currentPage: null,
27 |
28 | /**
29 | * Map views to dom
30 | * @param settings
31 | * @returns {SwitchLayout}
32 | */
33 | applyViews: function( settings ){
34 |
35 | if(this._currentPage === null || this._currentPage === undefined || this._currentPage === 'content_page2'){
36 | this._currentPage = 'content_page1';
37 |
38 | } else if(this._currentPage === 'content_page1'){
39 | this._currentPage = 'content_page2';
40 | }
41 |
42 | if(!this.childViews[this._currentPage]){
43 | if(settings.content){
44 | this.setChildView(this._currentPage, settings.content);
45 | }
46 |
47 | } else if(this.childViews[this._currentPage] !== settings.content){
48 | if(settings.content){
49 | this.setChildView(this._currentPage, settings.content);
50 | }
51 |
52 | }
53 |
54 | if(!this._firstRender){
55 | //clear the dom before inserting the view
56 | this.$el.find('[data-childviews="' + this._currentPage + '"]').html('');
57 | //insert the view
58 | this.$el.find('[data-childviews="' + this._currentPage + '"]').html(settings.content.render().$el);
59 | }
60 |
61 | M.Layout.prototype.applyViews.apply(this, arguments);
62 | return this;
63 | },
64 |
65 | /**
66 | * Initialize the Transitions on first render then call the prototype
67 | * @private
68 | */
69 | _postRender: function(){
70 |
71 | if(this._firstRender){
72 | M.PageTransitions.init(this.$el.find('#m-main'));
73 | }
74 | M.Layout.prototype._postRender.apply(this, arguments);
75 | }
76 | });
77 |
--------------------------------------------------------------------------------
/src/ui/layouts/switch-menu-header-content.js:
--------------------------------------------------------------------------------
1 | // Copyright (c) 2013 M-Way Solutions GmbH
2 | // http://github.com/mwaylabs/The-M-Project/blob/absinthe/MIT-LICENSE.txt
3 |
4 | (function( scope ) {
5 |
6 | /**
7 | * the switchlayout template
8 | * @type {string}
9 | */
10 | var switchTemplate = M.SwitchLayout.prototype.template;
11 | /**
12 | * the header template
13 | * @type {string}
14 | */
15 |
16 | var headerTemplate = M.HeaderLayout.prototype.template;
17 | /**
18 | * add a header to the both content container
19 | * @type {string}
20 | */
21 | var myTemplate = switchTemplate.replace(/m-page-1">/gi, 'm-page-1">' + headerTemplate.replace(/data-childviews="header"/gi, 'data-childviews="content_page1_header"'));
22 | myTemplate = myTemplate.replace(/m-page-2">/gi, 'm-page-2">' + headerTemplate.replace(/data-childviews="header"/gi, 'data-childviews="content_page2_header"'));
23 |
24 | /**
25 | * A Switchlayout with a header and content
26 | * @type {*|Object|void}
27 | */
28 | M.SwitchMenuHeaderContentLayout = M.SwitchHeaderContentLayout.extend({
29 |
30 | _type: 'M.SwitchHeaderContentLayout',
31 |
32 | /**
33 | * the template - a combination of the header and switch template
34 | * @type {string}
35 | */
36 | template: myTemplate,
37 |
38 | cssClass: 'switch-menu-header-content-layout',
39 |
40 | menu: null,
41 |
42 | /**
43 | * The content gets mapped to the DOM via the Switchlayout. Then map the header to the Layout.
44 | * @param {Object} the views to display
45 | * @returns {SwitchHeaderContentLayout}
46 | */
47 | applyViews: function( settings ) {
48 | if( !this.menu ) {
49 | if( settings.menuContent && M.MenuView.prototype.isPrototypeOf(settings.menuContent) ) {
50 | this.menu = settings.menuContent;
51 | this.setChildView('menu', settings.menuContent);
52 | this.menu.render();
53 | this.$el.append(this.menu.$el);
54 | } else {
55 | this.menu = M.MenuView.extend().create();
56 | this.setChildView('menu', this.menu);
57 | this.menu.setChildView('menu-content', settings.menuContent);
58 | this.menu.render();
59 | this.$el.append(this.menu.$el);
60 | }
61 | }
62 | var that = this;
63 | M.SwitchHeaderContentLayout.prototype.applyViews.apply(this, [settings]);
64 |
65 | return this;
66 | }
67 | });
68 |
69 | })(this);
--------------------------------------------------------------------------------
/src/ui/themes.js:
--------------------------------------------------------------------------------
1 | // Copyright (c) 2013 M-Way Solutions GmbH
2 | // http://github.com/mwaylabs/The-M-Project/blob/absinthe/MIT-LICENSE.txt
3 |
4 | /**
5 | *
6 | * @module M.Themes
7 | * @type {*}
8 | * @extends M.Object
9 | */
10 | M.Themes = M.Object.design({
11 | DEFAULT_THEME: 'basic',
12 |
13 | basic: {},
14 |
15 | _currentThemeName: 'basic',
16 |
17 | _themes: {},
18 |
19 | registerTemplateForTheme: function (themeName, templateName, template, override) {
20 | override = override || false;
21 |
22 | var theme = this._getThemeByName(themeName);
23 | if (!theme) {
24 | this._createThemeWithName(themeName);
25 | }
26 |
27 | var exists = this._getTemplateByNameForTheme(themeName, templateName) !== '';
28 | if (!exists || override) {
29 | this._themes[ themeName ][ templateName ] = template;
30 | return true;
31 | }
32 |
33 | console.warn('Template "' + templateName + '" already defined for theme "' + themeName + '"');
34 | return false;
35 | },
36 |
37 | getTemplateByName: function (templateName) {
38 |
39 | var template = this.getTemplateByNameForTheme(this._currentThemeName, templateName);
40 | if (template === '' && this._currentThemeName !== this.DEFAULT_THEME) {
41 | console.log('Template "' + templateName + '" not defined for theme "' + this._currentThemeName + '", switched to default theme "' + this.DEFAULT_THEME + '"');
42 | template = this.getTemplateByNameForTheme(this.DEFAULT_THEME, templateName);
43 | }
44 | return template;
45 | },
46 |
47 | getTemplateByNameForTheme: function (themeName, templateName) {
48 | var template = this._getTemplateByNameForTheme(themeName, templateName);
49 | if (template) {
50 | return template;
51 | }
52 | console.warn('Template "' + templateName + '" not defined for theme "' + themeName + '"');
53 | return '';
54 | },
55 |
56 | _getTemplateByNameForTheme: function (themeName, templateName) {
57 | var theme = this._getThemeByName(themeName);
58 | if (theme && theme[templateName]) {
59 | return theme[templateName];
60 | }
61 | return '';
62 | },
63 |
64 | _createThemeWithName: function (name) {
65 | this._themes[ name ] = {};
66 | },
67 |
68 | _getThemeByName: function (name) {
69 | if (this._themes[ name ]) {
70 | return this._themes[ name ];
71 | }
72 | return null;
73 | }
74 | });
75 |
--------------------------------------------------------------------------------
/src/ui/views/button.js:
--------------------------------------------------------------------------------
1 | // Copyright (c) 2013 M-Way Solutions GmbH
2 | // http://github.com/mwaylabs/The-M-Project/blob/absinthe/MIT-LICENSE.txt
3 |
4 | /**
5 | * M.ButtonView inherits from M.View
6 | * @module M.ButtonView
7 | *
8 | * @type {*}
9 | * @extends M.View
10 | */
11 | M.ButtonView = M.View.extend({
12 |
13 | /**
14 | * The type of the object
15 | * @private
16 | */
17 | _type: 'M.ButtonView',
18 |
19 | /**
20 | * The template of the object before initializing it.
21 | * @private
22 | */
23 | _templateString: M.TemplateManager.get('button.ejs'),
24 |
25 | /**
26 | * The active state of the button. Use isActive and setActive to change this property.
27 | * @private
28 | */
29 | _isActive: YES,
30 |
31 | /**
32 | * sets the view in the creation process to be enabled or disabled
33 | * @type {Boolean}
34 | */
35 | enabled: YES,
36 |
37 | initialize:function(){
38 | this.value = this.value || '';
39 | M.View.prototype.initialize.apply(this, arguments);
40 | },
41 |
42 | _assignTemplateValues: function() {
43 | M.View.prototype._assignTemplateValues.apply(this, arguments);
44 | this._templateValues.icon = this.icon ? this.icon : '';
45 | },
46 |
47 | _addClassNames: function() {
48 | M.View.prototype._addClassNames.apply(this, arguments);
49 | var value = this._getValue();
50 | if(value !== '' && this.icon && this.icon !== ''){
51 | this.$el.addClass('has-icon');
52 | } else if(value === '' && this.icon && this.icon !== ''){
53 | this.$el.addClass('is-icon-only');
54 | }
55 | },
56 |
57 | isActive: function() {
58 | return this._isActive();
59 | },
60 |
61 | activate: function() {
62 | this._isAcitve = YES;
63 | this.$el.addClass('active');
64 |
65 | },
66 |
67 | deactivate: function() {
68 | this._isAcitve = NO;
69 | this.$el.removeClass('active');
70 | },
71 |
72 | _postRender: function() {
73 | M.View.prototype._postRender.apply(this, arguments);
74 | if( this.enabled === NO && this.disable ) {
75 | this.disable();
76 | }
77 | }
78 |
79 | }).implements([M.ActiveState, M.ViewEnableState]);
--------------------------------------------------------------------------------
/src/ui/views/buttongroup.js:
--------------------------------------------------------------------------------
1 | // Copyright (c) 2013 M-Way Solutions GmbH
2 | // http://github.com/mwaylabs/The-M-Project/blob/absinthe/MIT-LICENSE.txt
3 |
4 | /**
5 | * @module M.ButtonGroupView
6 | * @type {*}
7 | * @extends M.View
8 | */
9 | M.ButtonGroupView = M.View.extend({
10 |
11 | _type: 'M.ButtonGroupView',
12 |
13 | _templateString: M.TemplateManager.get('buttongroup.ejs'),
14 |
15 | _internalCssClasses: 'clearfix',
16 |
17 | setActive: function( view ) {
18 |
19 | var setActiveView = M.isView(view) ? view : this._getChildView(view);
20 | _.each(this.childViews, function( child ) {
21 | child.deactivate();
22 | }, this);
23 | setActiveView.activate();
24 | },
25 |
26 | getActive: function() {
27 | return _.find(this._childViews, function( view ) {
28 | return view.isActive();
29 | }, this);
30 | },
31 |
32 | initialize: function() {
33 | M.View.prototype.initialize.apply(this, arguments);
34 | var that = this;
35 | if( this._childViews ) {
36 | _.each(this._childViews, function( child, key ) {
37 |
38 | this._childViews[key] = child.extend({
39 | _isInButtonGroup: YES,
40 | _internalEvents: {
41 | touchstart: [function( events, element ) {
42 | that.setActive(element);
43 | }],
44 | mousedown: [function( events, element ) {
45 | that.setActive(element);
46 | }]
47 | }
48 | });
49 | }, this);
50 | }
51 |
52 | },
53 |
54 | _preRender: function() {
55 | M.View.prototype._preRender.apply(this, arguments);
56 | _.each(this.childViews, function( child ) {
57 | if( child.selected ) {
58 | this.setActive(child);
59 | }
60 | }, this);
61 | },
62 |
63 | _addClassNames: function() {
64 | M.View.prototype._addClassNames.apply(this, arguments);
65 | }
66 | });
67 |
--------------------------------------------------------------------------------
/src/ui/views/checkboxlist.js:
--------------------------------------------------------------------------------
1 | // Copyright (c) 2013 M-Way Solutions GmbH
2 | // http://github.com/mwaylabs/The-M-Project/blob/absinthe/MIT-LICENSE.txt
3 |
4 | /**
5 | * @module M.CheckboxlistView
6 | *
7 | * @type {*}
8 | * @extends M.SelectionlistView
9 | */
10 | M.CheckboxlistView = M.SelectionlistView.extend({
11 |
12 | /**
13 | * The type of the object
14 | * @private
15 | */
16 | _type: 'M.CheckboxlistView',
17 |
18 | /**
19 | * The template of the object before initializing it.
20 | * @private
21 | */
22 | _templateString: M.TemplateManager.get('checkboxlist.ejs'),
23 |
24 | _optionTemplate: _.tmpl(M.TemplateManager.get('checkboxoption.ejs')),
25 |
26 | _optionsContainer: 'checkbox'
27 |
28 | });
29 |
30 |
31 |
--------------------------------------------------------------------------------
/src/ui/views/debug.js:
--------------------------------------------------------------------------------
1 | // Copyright (c) 2013 M-Way Solutions GmbH
2 | // http://github.com/mwaylabs/The-M-Project/blob/absinthe/MIT-LICENSE.txt
3 |
4 | /**
5 | * @module M.DebugView
6 | *
7 | * @type {*}
8 | * @extends M.View
9 | */
10 | M.DebugView = M.View.extend({
11 |
12 | _type: 'M.DebugView',
13 |
14 | _templateString: M.TemplateManager.get('debug.ejs'),
15 |
16 | _debugViewIsHidden: YES,
17 |
18 | cssClass: 'bg',
19 |
20 | useAsScope: YES,
21 |
22 | initialize: function() {
23 | M.View.prototype.initialize.apply(this, arguments);
24 | this._addShakeEvent();
25 | },
26 |
27 | hide: function() {
28 | this._debugViewIsHidden = YES;
29 | this.$el.hide();
30 | },
31 |
32 | show: function() {
33 | if( this._firstRender ) {
34 | $('body').append(this.render().$el);
35 | }
36 | this._debugViewIsHidden = NO;
37 | this.$el.show();
38 | },
39 |
40 | toggle: function() {
41 | if( this._debugViewIsHidden ) {
42 | this.show();
43 | } else {
44 | this.hide();
45 | }
46 | },
47 |
48 | toggleGrid: function() {
49 | this.$el.toggleClass('bg');
50 | this.childViews['debug-grid'].$el.toggle();
51 | },
52 |
53 | androidLightTheme: function() {
54 | this.resetTheme();
55 | $('html').addClass('android-light');
56 | },
57 |
58 | iosTheme: function() {
59 | this.resetTheme();
60 | $('html').addClass('ios');
61 | },
62 |
63 | resetTheme: function() {
64 | $('html').removeClass('android').removeClass('android-light').removeClass('android-dark').removeClass('ios');
65 | },
66 |
67 | _addShakeEvent: function() {
68 | var that = this;
69 | window.addEventListener('shake', function() {
70 | that.toggle();
71 | }, false);
72 | }
73 | }, {
74 | 'debug-menu': M.ButtonGroupView.extend({
75 | cssClass: 'debug-menu'
76 | }, {
77 | toggleGrid: M.ButtonView.extend({
78 | value: 'Toggle grid',
79 | events: {
80 | tap: 'toggleGrid'
81 | }
82 | }),
83 |
84 | androidLight: M.ButtonView.extend({
85 | value: 'android-light theme',
86 | events: {
87 | tap: 'androidLightTheme'
88 | }
89 | }),
90 |
91 | ios: M.ButtonView.extend({
92 | value: 'ios theme',
93 | events: {
94 | tap: 'iosTheme'
95 | }
96 | }),
97 |
98 | reset: M.ButtonView.extend({
99 | value: 'reset theme',
100 | events: {
101 | tap: 'resetTheme'
102 | }
103 | })
104 | }),
105 |
106 | 'debug-grid': M.View.extend({
107 | useElement: YES,
108 | template: (function() {
109 | var tpl = '
';
110 | for( var i = 0; i < 12; i++ ) {
111 | tpl += '
';
112 | }
113 | tpl += '
';
114 | return tpl;
115 | })()
116 | })
117 | });
--------------------------------------------------------------------------------
/src/ui/views/dialog.js:
--------------------------------------------------------------------------------
1 | // Copyright (c) 2013 M-Way Solutions GmbH
2 | // http://github.com/mwaylabs/The-M-Project/blob/absinthe/MIT-LICENSE.txt
3 |
4 | /**
5 | * @module M.DialogView
6 | *
7 | * @type {*}
8 | * @extends M.View
9 | */
10 | M.DialogView = M.View.extend({
11 |
12 | _type: 'M.DialogView',
13 |
14 | _templateString: M.TemplateManager.get('dialog.ejs')
15 |
16 | });
--------------------------------------------------------------------------------
/src/ui/views/image.js:
--------------------------------------------------------------------------------
1 | // Copyright (c) 2013 M-Way Solutions GmbH
2 | // http://github.com/mwaylabs/The-M-Project/blob/absinthe/MIT-LICENSE.txt
3 |
4 | /**
5 | * @module M.ImageView
6 | *
7 | * @type {*}
8 | * @extends M.View
9 | */
10 | M.ImageView = M.View.extend({
11 |
12 | _type: 'M.ImageView',
13 |
14 | _templateString: M.TemplateManager.get('image.ejs'),
15 |
16 | /**
17 | * Represents the alt attribute of the img tag
18 | */
19 | alt: null,
20 |
21 | initialize: function () {
22 | M.View.prototype.initialize.apply(this, arguments);
23 | this.alt = this.alt || '';
24 | return this;
25 | },
26 |
27 | /**
28 | * Override this function to add 'alt' parameter
29 | * @private
30 | * @returns this
31 | */
32 | _assignTemplateValues: function () {
33 |
34 | M.View.prototype._assignTemplateValues.apply(this, arguments);
35 |
36 | var _value = this._getValue();
37 |
38 | if (this.model) {
39 | if (M.isModel(_value)) {
40 | } else {
41 | this._templateValues.alt = this.model.get(this.alt.attribute);
42 | }
43 | } else if (_value || typeof _value === 'string') {
44 | this._templateValues.alt = this.alt;
45 | }
46 | return this;
47 | }
48 | });
--------------------------------------------------------------------------------
/src/ui/views/loader.js:
--------------------------------------------------------------------------------
1 | // Copyright (c) 2013 M-Way Solutions GmbH
2 | // http://github.com/mwaylabs/The-M-Project/blob/absinthe/MIT-LICENSE.txt
3 |
4 | /**
5 | *
6 | * The base implementation of a loader. Calling the show/toggle shows the loader.
7 | * Calling multiple times the show function with a different text will update the text.
8 | * Call hide/toggle for every show to hide the Loader.
9 | * To force the hidding pass true to the hide call
10 | *
11 | * @module M.LoaderView
12 | * @extends M.ModalView
13 | * @type {*|Object|void}
14 | *
15 | * @example
16 | * var loader = M.LoaderView.extend().create().render();
17 | * //show loader
18 | * loader.show('loading');
19 | * //hide loader
20 | * loader.hide();
21 | * //show loader
22 | * loader.toggle('loading second time');
23 | * //hide loader
24 | * loader.toggle();
25 | * //show loader
26 | * loader.show('loading');
27 | * //udpte text
28 | * loader.show('still loading');
29 | * //force hidding
30 | * loader.hide(true);
31 | *
32 | */
33 | M.LoaderView = M.ModalView.extend({
34 |
35 | /**
36 | * The type of the View
37 | * @private
38 | * @type {String}
39 | */
40 | _type: 'M.LoaderView',
41 |
42 | /**
43 | * Defines that the loader view can't be closed by clicking on the overlay.
44 | * @type {String}
45 | */
46 | hideOnOverlayClick: NO,
47 |
48 | /**
49 | * Show the loader
50 | * @param {String} text - The text for the Loader
51 | * @returns {LoaderView}
52 | */
53 | show: function( text ) {
54 | text = text || '';
55 | M.ModalView.prototype.show.apply(this, arguments);
56 | this.$el.find('.m-loaderview-inner-message').html(text);
57 | return this;
58 | }
59 | }, {
60 | content: M.View.extend({
61 |
62 | /**
63 | * The template of the view
64 | * @private
65 | * @type {function}
66 | */
67 | _templateString: M.TemplateManager.get('loader.ejs'),
68 |
69 | /**
70 | * This function needs to be implemented to render the view if there is no value given
71 | * @returns {Boolean|Function|YES}
72 | * @private
73 | */
74 | _attachToDom: function() {
75 | return YES;
76 | }
77 | })
78 | });
79 |
80 |
81 | /**
82 | *
83 | * @module M.Loader
84 | * @static
85 | * Static implementation of the LoaderView
86 | *
87 | * @type {*|Prompt|String|this}
88 | * @example
89 | * M.ButtonView.extend({
90 | grid: 'col-xs-12',
91 | value: 'Toggle LoaderView',
92 | events: {
93 | tap: function() {
94 | M.Loader.toggle();
95 | }
96 | }
97 | */
98 | M.Loader = M.LoaderView.create().render();
--------------------------------------------------------------------------------
/src/ui/views/radiolist.js:
--------------------------------------------------------------------------------
1 | // Copyright (c) 2013 M-Way Solutions GmbH
2 | // http://github.com/mwaylabs/The-M-Project/blob/absinthe/MIT-LICENSE.txt
3 |
4 | /**
5 | * The {M.RadiolistView} view class render a group of
HTML elements.
6 | * An example would be ask the user for his favorite drink. The user can
7 | * choose between different drinks, but he can only select one of them.
8 | * @module M.RadiolistView
9 | *
10 | * @type {M.RadiolistView}
11 | * @extend {M.SelectionlistView}
12 | * @example
13 | *
14 | * M.RadioButtonView.extend({
15 | * scopeKey: 'userModel.favoriteDrink',
16 | * selectOptions: {
17 | * collection: [
18 | * {id: 1, name: 'Absinthe'},
19 | * {id: 2, name: 'Water'},
20 | * {id: 3, name: 'Dr Pepper'}
21 | * ],
22 | * labelPath: 'name',
23 | * valuePath: 'id'
24 | * }
25 | * });
26 | */
27 |
28 | M.RadiolistView = M.SelectionlistView.extend({
29 |
30 | /**
31 | * The type of the object
32 | * @private
33 | */
34 | _type: 'M.RadiolistView',
35 |
36 | /**
37 | * The template of the object before initializing it.
38 | * @private
39 | */
40 | _templateString: M.TemplateManager.get('radiolist.ejs'),
41 |
42 | /**
43 | * The template of an option before initializing it.
44 | * @private
45 | */
46 | _optionTemplate: _.tmpl(M.TemplateManager.get('radiooption.ejs')),
47 |
48 | /**
49 | * Selector name which is used internally to determine the parent dom element.
50 | * @private
51 | */
52 | _optionsContainer: 'radio'
53 | }).implements([M.ActiveState]);
54 |
55 |
56 |
--------------------------------------------------------------------------------
/src/ui/views/searchfield.js:
--------------------------------------------------------------------------------
1 | // Copyright (c) 2013 M-Way Solutions GmbH
2 | // http://github.com/mwaylabs/The-M-Project/blob/absinthe/MIT-LICENSE.txt
3 |
4 | /**
5 | * @module M.SearchfieldView
6 | *
7 | * @type {*}
8 | * @extends M.TextfieldView
9 | */
10 | M.SearchfieldView = M.TextfieldView.extend({
11 |
12 | _type: 'M.SearchfieldView',
13 |
14 | placeholder: 'Search',
15 |
16 | _templateString: M.TemplateManager.get('searchfield.ejs'),
17 |
18 | initialize: function () {
19 | M.View.prototype.initialize.apply(this);
20 | },
21 |
22 | _assignTemplateValues: function () {
23 | M.TextfieldView.prototype._assignTemplateValues.apply(this);
24 | this._templateValues.placeholder = this.placeholder || '';
25 | }
26 | });
27 |
--------------------------------------------------------------------------------
/src/ui/views/select.js:
--------------------------------------------------------------------------------
1 | // Copyright (c) 2013 M-Way Solutions GmbH
2 | // http://github.com/mwaylabs/The-M-Project/blob/absinthe/MIT-LICENSE.txt
3 |
4 | /**
5 | * @module M.SelectView
6 | *
7 | * @type {*}
8 | * @extends M.View
9 | */
10 | M.SelectView = M.View.extend({
11 |
12 | _type: 'M.SelectView',
13 |
14 | isMultiple: NO,
15 |
16 | _templateString: M.TemplateManager.get('select.ejs'),
17 |
18 | _assignBinding: function () {
19 | M.View.prototype._assignBinding.apply(this, arguments);
20 | if (this.selectOptions) {
21 | _.each(this.bindings, function (value) {
22 | value.selectOptions = this.selectOptions;
23 | }, this);
24 | }
25 | return this;
26 | },
27 |
28 | _assignTemplateValues: function () {
29 | M.View.prototype._assignTemplateValues.apply(this);
30 | this._templateValues.isMultiple = this.isMultiple;
31 | }
32 | });
--------------------------------------------------------------------------------
/src/ui/views/selectionlist.js:
--------------------------------------------------------------------------------
1 | // Copyright (c) 2013 M-Way Solutions GmbH
2 | // http://github.com/mwaylabs/The-M-Project/blob/absinthe/MIT-LICENSE.txt
3 |
4 | /**
5 | * @module M.SelectionlistView
6 | *
7 | * @type {*}
8 | * @extends M.View
9 | */
10 | M.SelectionlistView = M.View.extend({
11 |
12 | /**
13 | * The type of the object
14 | * @private
15 | */
16 | _type: 'M.SelectionlistView',
17 |
18 | /**
19 | * The template of the object before initializing it.
20 | * @private
21 | */
22 | _template: null,
23 |
24 | _templateString: null,
25 |
26 | /**
27 | * The template of an option before initializing it.
28 | * @private
29 | */
30 | _optionTemplate: null,
31 |
32 | /**
33 | * Selector name which is used internally to determine the parent dom element.
34 | * @private
35 | */
36 | _optionsContainer: '',
37 |
38 | /**
39 | * Override this function to call the '_renderOptions' method.
40 | *
41 | * @override
42 | * @returns {this}
43 | * @private
44 | */
45 | _render: function () {
46 |
47 | M.View.prototype._render.apply(this, arguments);
48 | this._renderOptions();
49 | return this;
50 | },
51 |
52 | /**
53 | * This method renders the options based on the selectOptions property.
54 | *
55 | * @returns {this}
56 | * @private
57 | */
58 | _renderOptions: function () {
59 |
60 | if (this.selectOptions && this.selectOptions.collection) {
61 | var dom = '';
62 | _.each(this.selectOptions.collection, function (value) {
63 | dom += this._optionTemplate({
64 | name: this.cid + '-option',
65 | value: value[this.selectOptions.valuePath || 'value'],
66 | label: value[this.selectOptions.labelPath || 'label']
67 | });
68 | }, this);
69 |
70 | this.$el.children('div').children('[data-childviews="' + this._optionsContainer + '-options"]').append(dom);
71 | }
72 |
73 | return this;
74 | }
75 | }).implements([M.ActiveState]);
76 |
77 |
78 |
--------------------------------------------------------------------------------
/src/ui/views/slider.js:
--------------------------------------------------------------------------------
1 | // Copyright (c) 2013 M-Way Solutions GmbH
2 | // http://github.com/mwaylabs/The-M-Project/blob/absinthe/MIT-LICENSE.txt
3 |
4 | /**
5 | * @module M.SliderView
6 | *
7 | * @type {*}
8 | * @extends M.View
9 | */
10 | M.SliderView = M.View.extend({
11 |
12 | _type: 'M.SliderView',
13 |
14 | _templateString: M.TemplateManager.get('slider.ejs'),
15 |
16 | _getEventOptions: function () {
17 | return {
18 | 'prevent_default': false,
19 | 'no_mouseevents': true
20 | };
21 | }
22 |
23 | });
--------------------------------------------------------------------------------
/src/ui/views/tab.js:
--------------------------------------------------------------------------------
1 | // Copyright (c) 2013 M-Way Solutions GmbH
2 | // http://github.com/mwaylabs/The-M-Project/blob/absinthe/MIT-LICENSE.txt
3 |
4 | /**
5 | * @module M.TabView
6 | *
7 | * @type {*}
8 | * @extends M.View
9 | */
10 | M.TabView = M.View.extend({
11 |
12 | _type: 'M.TabView',
13 |
14 | cssClass: 'm-page m-tab'
15 |
16 | });
--------------------------------------------------------------------------------
/src/ui/views/tabbarbuttongroup.js:
--------------------------------------------------------------------------------
1 | // Copyright (c) 2013 M-Way Solutions GmbH
2 | // http://github.com/mwaylabs/The-M-Project/blob/absinthe/MIT-LICENSE.txt
3 |
4 | /**
5 | * @module M.ButtonGroupView
6 | * @type {*}
7 | * @extends M.View
8 | */
9 | M.TabbarButtonGroupView = M.ButtonGroupView.extend({
10 |
11 | _type: 'M.TabbarButtonGroupView',
12 |
13 | initialize: function () {
14 | M.View.prototype.initialize.apply(this, arguments);
15 | var that = this;
16 | if (this._childViews) {
17 | var gridSize = M.CONST.GRID.COLUMNS / Object.keys(this._childViews).length;
18 | _.each(this._childViews, function (child, key) {
19 | this._childViews[key] = child.extend({
20 | grid: 'col-xs-' + gridSize,
21 | _internalEvents: {
22 | tap: [function (events, element) {
23 | that.setActive(element);
24 | }]
25 | }
26 | });
27 | }, this);
28 | }
29 |
30 | },
31 | });
32 |
--------------------------------------------------------------------------------
/src/ui/views/template_manager.js:
--------------------------------------------------------------------------------
1 | // Copyright (c) 2013 M-Way Solutions GmbH
2 | // http://github.com/mwaylabs/The-M-Project/blob/absinthe/MIT-LICENSE.txt
3 |
4 | /**
5 | * The M.TemplateManager is a singleton instance which
6 | * contain all our templates for the framework views.
7 | * You can retrieves a template with the get() method.
8 | *
9 | * @module M.TemplateManager
10 | *
11 | * @type {*}
12 | * @extends M.Object
13 | * @example
14 | *
15 | * var tpl = M.TemplateManager.get('ListView');
16 | * console.log( tpl ); //
17 | *
18 | */
19 | M.TemplateManager = M.Object.design({
20 |
21 | _currentUI: 'default',
22 |
23 | /**
24 | * Returns the template with the given name or
25 | * the default template for M.View if there is no such template.
26 | *
27 | * @param {String} name
28 | * @returns {String}
29 | */
30 | get: function( template, ui ) {
31 |
32 | ui = ui || M.TemplateManager._currentUI;
33 |
34 | var tpl = M.Templates[ui][template];
35 |
36 | if(tpl) {
37 | return tpl;
38 | }
39 |
40 | if(ui !== 'default') {
41 | return this.get(template, 'default');
42 | }
43 |
44 | return null;
45 | }
46 | });
47 |
--------------------------------------------------------------------------------
/src/ui/views/text.js:
--------------------------------------------------------------------------------
1 | // Copyright (c) 2013 M-Way Solutions GmbH
2 | // http://github.com/mwaylabs/The-M-Project/blob/absinthe/MIT-LICENSE.txt
3 |
4 | /**
5 | * A View to display text. It's like a Textfieldview with icon and label but without edit mode
6 | * @type {*|Object|void}
7 | * @module M.TextView
8 | * @example
9 | * M.TextView.extend({
10 | label: 'Cloud',
11 | icon: 'fa-cloud',
12 | value: 'Cloud based Saas'
13 | }),
14 | *
15 | */
16 | M.TextView = M.View.extend({
17 |
18 | /**
19 | * The type of the input.
20 | * @private
21 | */
22 | _type: 'M.TextView',
23 |
24 | /**
25 | * The label of the input.
26 | */
27 | label: null,
28 |
29 | /**
30 | * String - The icon for a Textfieldview. Use a icon from font-awesome. Default is the icon on the left. give the parent div a class right and it will be displayed on the right
31 | *
32 | */
33 | icon: null,
34 |
35 | /**
36 | * the template of the input
37 | */
38 | _templateString: M.TemplateManager.get('text.ejs'),
39 |
40 | /**
41 | * Add all the template values
42 | */
43 | _assignTemplateValues: function() {
44 | M.View.prototype._assignTemplateValues.apply(this);
45 | this._addLabelToTemplateValues();
46 | this._addIconToTemplateValues();
47 | return this;
48 | },
49 |
50 | /**
51 | * Gets a internationalized version of the label and add this to the templateValues
52 | * @private
53 | */
54 | _addLabelToTemplateValues: function() {
55 | this._templateValues.label = this._getInternationalizedTemplateValue(this.label);
56 | return this;
57 | },
58 |
59 | /**
60 | * Add the type of the icon to the template values, if no icon is set the value is empty string
61 | * @private
62 | */
63 | _addIconToTemplateValues: function() {
64 | this._templateValues.icon = this.icon || '';
65 | },
66 |
67 | /**
68 | * This function needs to be implemented to render the view if there is no value given
69 | * @returns {Boolean|Function|YES}
70 | * @private
71 | */
72 | _attachToDom: function() {
73 | return YES;
74 | }
75 | });
--------------------------------------------------------------------------------
/src/ui/views/textarea.js:
--------------------------------------------------------------------------------
1 | // Copyright (c) 2013 M-Way Solutions GmbH
2 | // http://github.com/mwaylabs/The-M-Project/blob/absinthe/MIT-LICENSE.txt
3 |
4 | /**
5 | * @module M.TextareaView
6 | *
7 | * @type {*}
8 | * @extends M.TextfieldView
9 | */
10 | M.TextareaView = M.TextfieldView.extend({
11 |
12 | _type: 'M.TextareaView',
13 |
14 | _templateString: M.TemplateManager.get('textarea.ejs'),
15 |
16 | _attachToDom: function () {
17 | return YES;
18 | }
19 | });
--------------------------------------------------------------------------------
/src/ui/views/toast.js:
--------------------------------------------------------------------------------
1 | // Copyright (c) 2013 M-Way Solutions GmbH
2 | // http://github.com/mwaylabs/The-M-Project/blob/absinthe/MIT-LICENSE.txt
3 |
4 | /**
5 | * @module M.Toast
6 | *
7 | * @type {*}
8 | * @extends M.View
9 | *
10 | * @example
11 | * M.Toast.show('test');
12 | * M.Toast.show('test', M.Toast.CONST.CRISPY);
13 | *
14 | */
15 | M.Toast = M.View.extend({
16 |
17 | _type: 'M.ToastView',
18 |
19 | /**
20 | * the template of the toast
21 | *
22 | */
23 | _templateString: M.TemplateManager.get('toast.ejs'),
24 |
25 | /**
26 | * the id of the toast
27 | */
28 | id: null,
29 |
30 | /**
31 | * Add the toast to the 'body' after initialize it
32 | * @param settings
33 | */
34 | initialize: function (settings) {
35 | var that = this;
36 | that.id = _.uniqueId();
37 | that.text = settings.text || M.Toast.CONST.TEXT;
38 | $('body').append(that.render().$el);
39 |
40 | that.timeoutId = setTimeout(function () {
41 | that.remove();
42 | }, settings.timeout || M.Toast.CONST.MEDIUM);
43 | },
44 |
45 | /**
46 | * assign the values for the template engine
47 | * @private
48 | */
49 | _assignTemplateValues: function () {
50 | this._templateValues = {
51 | id: this.id,
52 | text: this.text
53 | };
54 | },
55 |
56 | /**
57 | * remove
58 | */
59 | remove: function() {
60 | M.View.prototype.remove.apply(this, arguments);
61 | if(this.timeoutId) {
62 | clearTimeout(this.timeoutId);
63 | }
64 | M.Toast._run();
65 | },
66 |
67 | /**
68 | * This function needs to be implemented to render the view if there is no value given
69 | * @returns {Boolean|Function|YES}
70 | * @private
71 | */
72 | _attachToDom: function() {
73 | return YES;
74 | }
75 |
76 | });
77 |
78 | M.Toast._stack = [];
79 | M.Toast._isSequencing = false;
80 | M.Toast._currentToast = null;
81 |
82 | /**
83 | * Show a toast
84 | * @param {String} text to display
85 | * @param {Number} milliseconds to show the toast
86 | * @returns {M.Toast}
87 | */
88 | M.Toast.show = function( options, timeout ) {
89 | if( typeof options === 'string' ) {
90 | options = {
91 | text: options,
92 | timeout: timeout
93 | };
94 | }
95 |
96 | // Push the toast into the stack
97 | this._stack.push(options);
98 |
99 | // Start sequence if it is not already running
100 | if( !this._isSequencing ) {
101 | this._isSequencing = true;
102 | this._run();
103 | }
104 | };
105 |
106 | /**
107 | * Removes all toasts from the sequence.
108 | */
109 | M.Toast.removeAll = function() {
110 | this._stack = [];
111 | if( this._currentToast ) {
112 | this._currentToast.remove();
113 | this._currentToast = null;
114 | }
115 | };
116 |
117 | M.Toast._run = function() {
118 | if( this._stack.length === 0 ) {
119 | this._isSequencing = false;
120 | return;
121 | }
122 | var options = this._stack.shift();
123 | this._currentToast = M.Toast.create(options);
124 | };
125 |
126 | M.Toast.CONST = {
127 | RAW: 500,
128 | MEDIUM: 2000,
129 | CRISPY: 4000,
130 | TEXT: ''
131 | };
--------------------------------------------------------------------------------
/src/ui/views/toggle.js:
--------------------------------------------------------------------------------
1 | // Copyright (c) 2013 M-Way Solutions GmbH
2 | // http://github.com/mwaylabs/The-M-Project/blob/absinthe/MIT-LICENSE.txt
3 |
4 | /**
5 | * @module M.ToggleView
6 | *
7 | * @type {*}
8 | * @extends M.View
9 | */
10 | M.ToggleView = M.View.extend({
11 |
12 | _type: 'M.ToggleView',
13 |
14 | _templateString: M.TemplateManager.get('toggle.ejs'),
15 |
16 | initialize: function () {
17 | M.View.prototype.initialize.apply(this, arguments);
18 | },
19 |
20 | render: function (settings) {
21 | //this._assignValue();
22 | this._preRender(settings);
23 | this._render(settings);
24 | this._renderChildViews(settings);
25 | this._postRender(settings);
26 | return this;
27 | }
28 |
29 | });
--------------------------------------------------------------------------------
/src/ui/views/toolbar.js:
--------------------------------------------------------------------------------
1 | // Copyright (c) 2013 M-Way Solutions GmbH
2 | // http://github.com/mwaylabs/The-M-Project/blob/absinthe/MIT-LICENSE.txt
3 |
4 | /**
5 | * @module M.ToolbarView
6 | *
7 | * @type {*}
8 | * @extends M.View
9 | */
10 | M.ToolbarView = M.View.extend({
11 |
12 | /**
13 | * The type of the view
14 | * @private
15 | * @type {String}
16 | */
17 | _type: 'M.ToolbarView',
18 |
19 | /**
20 | * The template of the view
21 | * @private
22 | * @type {function}
23 | */
24 | _templateString: M.TemplateManager.get('toolbar.ejs')
25 |
26 | });
--------------------------------------------------------------------------------
/src/utility/animation.js:
--------------------------------------------------------------------------------
1 | // Copyright (c) 2013 M-Way Solutions GmbH
2 | // http://github.com/mwaylabs/The-M-Project/blob/absinthe/MIT-LICENSE.txt
3 |
4 | /**
5 | *
6 | * @module M.Animation
7 | * @type {*}
8 | * @extends M.Object
9 | */
10 | M.Animation = M.Object.design({
11 |
12 | /**
13 | * Indicating whether css animations are supported or not.
14 | *
15 | * @returns {boolean}
16 | */
17 | animationSupport: (function() {
18 | // CSS animations are supported by Android < 4 devices but only if a single property is changed.
19 | if( M.Environment.isLowerThanAndroid4 ) {
20 | return false;
21 | }
22 | if( M.Environment.isLowerThaniPhone4S ) {
23 | //return false;
24 | }
25 | return Modernizr.cssanimations;
26 | })(),
27 |
28 | /**
29 | * Indicating whether css transitions are supported or not.
30 | *
31 | * @returns {boolean}
32 | */
33 | transitionSupport: (function() {
34 | return Modernizr.csstransitions;
35 | })(),
36 |
37 | /**
38 | * Returns the prefixed css property for animationEnd.
39 | *
40 | * @returns {String}
41 | */
42 | animationEndEventName: (function() {
43 | var cssEvents = {
44 | 'WebkitAnimation': 'webkitAnimationEnd',
45 | 'OAnimation': 'oAnimationEnd',
46 | 'msAnimation': 'MSAnimationEnd',
47 | 'animation': 'animationend'
48 | };
49 | return cssEvents[ Modernizr.prefixed('animation') ];
50 | }()),
51 |
52 | /**
53 | * Returns the prefixed css property for transitionEnd.
54 | *
55 | * @returns {String}
56 | */
57 | transitionEndEventName: (function() {
58 | var cssEvents = {
59 | 'WebkitTransition': 'webkitTransitionEnd',
60 | 'OTransition': 'oTransitionEnd',
61 | 'msTransition': 'MSTransitionEnd',
62 | 'transition': 'transitionend'
63 | };
64 | return cssEvents[ Modernizr.prefixed('transition') ];
65 | }())
66 | });
--------------------------------------------------------------------------------
/src/utility/date.js:
--------------------------------------------------------------------------------
1 | // Copyright (c) 2013 M-Way Solutions GmbH
2 | // http://github.com/mwaylabs/The-M-Project/blob/absinthe/MIT-LICENSE.txt
3 |
4 | /**
5 | *
6 | * @module M.Date
7 | *
8 | * @extends M.Object
9 | */
10 | M.Date = {
11 |
12 | /**
13 | * This method is used to create a new instance of M.Date based on the data
14 | * library moment.js.
15 | *
16 | * @returns {Object}
17 | */
18 | create: function() {
19 | var m = moment.apply(this, arguments);
20 | return _.extend(m, this);
21 | }
22 | };
23 |
--------------------------------------------------------------------------------
/src/utility/i18n_item.js:
--------------------------------------------------------------------------------
1 | // Copyright (c) 2013 M-Way Solutions GmbH
2 | // http://github.com/mwaylabs/The-M-Project/blob/absinthe/MIT-LICENSE.txt
3 |
4 | /**
5 | *
6 | * @module M.I18NItem
7 | *
8 | * @type {*}
9 | * @extends M.Object
10 | */
11 | M.I18NItem = M.Object.design({
12 |
13 | /**
14 | * The type of this object.
15 | *
16 | * @type {String}
17 | * @private
18 | */
19 | _type: 'M.I18NItem',
20 |
21 | /**
22 | * The translation key. Used to identify the locale item.
23 | *
24 | * @type {String}
25 | */
26 | key: null,
27 |
28 | /**
29 | * The translation placeholder as a key-value pair.
30 | * Used to replace all {{placeholderName}} in the locale string
31 | * with the appropriate value.
32 | *
33 | * Example:
34 | * {
35 | * username: 'Tom',
36 | * status: 'offline'
37 | * }
38 | *
39 | * @type {Object}
40 | */
41 | placeholder: null,
42 |
43 | /**
44 | * Creates a new instance with the given key and placeholder.
45 | * Used to hold the key and placeholder for later use.
46 | *
47 | * @param key {String}
48 | * @param placeholder {String}
49 | * @returns {M.I18NItem}
50 | */
51 | create: function (key, placeholder) {
52 | if(!key) {
53 | return null;
54 | }
55 |
56 | this.key = key;
57 | if(placeholder) {
58 | this.placeholder = placeholder;
59 | }
60 | return _.extend({}, this);
61 | }
62 | });
--------------------------------------------------------------------------------
/src/utility/uuid.js:
--------------------------------------------------------------------------------
1 | // Copyright (c) 2013 M-Way Solutions GmbH
2 | // http://github.com/mwaylabs/The-M-Project/blob/absinthe/MIT-LICENSE.txt
3 |
4 | // Returns a unique identifier
5 |
6 | /**
7 | *
8 | * @module M.UniqueId
9 | *
10 | * @type {*}
11 | * @extends M.Object
12 | */
13 | M.UniqueId = M.Object.design({
14 | uuid: function(len, radix) {
15 | // based on Robert Kieffer's randomUUID.js at http://www.broofa.com
16 | var chars = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz'.split('');
17 | var uuid = [];
18 | //len = len ? len : 32;
19 | radix = radix || chars.length;
20 | var i;
21 |
22 | if (len) {
23 | for (i = 0; i < len; i++) {
24 | uuid[i] = chars[0 | Math.random() * radix];
25 | }
26 | } else {
27 | // rfc4122, version 4 form
28 | var r;
29 |
30 | // rfc4122 requires these characters
31 | uuid[8] = uuid[13] = uuid[18] = uuid[23] = '-';
32 | uuid[14] = '4';
33 |
34 | // Fill in random data. At i==19 set the high bits of clock sequence as
35 | // per rfc4122, sec. 4.1.5
36 | for (i = 0; i < 36; i++) {
37 | if (!uuid[i]) {
38 | r = 0 | Math.random() * 16;
39 | uuid[i] = chars[(i === 19) ? (r & 0x3) | 0x8 : r];
40 | }
41 | }
42 | }
43 | return uuid.join('');
44 | }
45 | });
--------------------------------------------------------------------------------
/tasks/compileTemplates.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | module.exports = function( grunt ) {
4 |
5 | // Internal libs
6 | var _ = require('lodash');
7 |
8 | grunt.registerTask('compileTemplates', function() {
9 |
10 | var basePath = 'src/templates/';
11 | var dest = 'src/templates.js';
12 |
13 | var files = grunt.file.expand(basePath + '**/*.ejs');
14 | var result = {};
15 |
16 | _.each(files, function( path ) {
17 |
18 | var helper = path.replace(basePath, '').split('/');
19 | var theme = helper[0];
20 | var template = helper[1];
21 |
22 | if( !result[theme] ) {
23 | result[theme] = {};
24 | }
25 | grunt.log.debug(helper[1]);
26 | result[theme][template] = grunt.file.read(path);
27 | });
28 |
29 | if(grunt.file.exists(dest)) {
30 | grunt.file.delete(dest);
31 | }
32 |
33 | var content = grunt.file.read(__dirname + '/tpl/templates.txt');
34 | result = JSON.stringify(result);
35 |
36 | grunt.template.addDelimiters('square-brackets', '[%', '%]');
37 | content = grunt.template.process(content, {data: {vars: result}, delimiters: 'square-brackets'});
38 |
39 | grunt.file.write(dest, content);
40 | });
41 | }
--------------------------------------------------------------------------------
/tasks/extractSassVars.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | module.exports = function( grunt ) {
4 |
5 | // Internal libs
6 | var _ = require('lodash');
7 |
8 | grunt.registerMultiTask('extractSassVars', 'Convert sass variables to javascript', function() {
9 | var collection = [];
10 | var regExp = /\$([^:]+):[\s]+([^;]+);/g;
11 | var results;
12 |
13 | // Iterate over all specified file groups.
14 | this.files.forEach(function( f ) {
15 | // Concat specified files.
16 | var sassVars = f.src.filter(function( filepath ) {
17 | // Warn on and remove invalid source files (if nonull was set).
18 | if( !grunt.file.exists(filepath) ) {
19 | grunt.log.warn('Source file "' + filepath + '" not found.');
20 | return false;
21 | } else {
22 | return true;
23 | }
24 | }).map(function( filepath ) {
25 | // Read file source.
26 | var regex = new RegExp('^resources/sass/themes/([^/]*)');
27 | var themeName = filepath.match(regex)[1];
28 | return {
29 | theme: themeName,
30 | content: grunt.file.read(filepath)
31 | };
32 | });
33 | _.each(sassVars, function( item ) {
34 | while( (results = regExp.exec(item.content)) != null ) {
35 | if( !item.vars ) {
36 | item.vars = {};
37 | }
38 | item.vars[results[1]] = results[2];
39 | }
40 | delete item.content;
41 | });
42 | _.each(sassVars, function( item ) {
43 | var group = item.vars;
44 |
45 | for( var key in group ) {
46 | for( var key2 in group ) {
47 | group[key2] = group[key2].replace(new RegExp('\\$' + key, 'gi'), group[key]);
48 | }
49 | }
50 | });
51 | var vars = {};
52 | _.each(sassVars, function( item ) {
53 | vars[item.theme] = item.vars
54 | });
55 | var output = grunt.file.read(__dirname + '/tpl/themevars.txt');
56 | output = grunt.template.process(output, {data: {vars: JSON.stringify(vars, null, 4)}});
57 |
58 | // Write the destination file.
59 | grunt.file.write(f.dest, output);
60 |
61 | // Print a success message.
62 | grunt.log.writeln('File "' + f.dest + '" created.');
63 | });
64 | });
65 | }
--------------------------------------------------------------------------------
/tasks/rewriteMarkdownFiles.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | module.exports = function( grunt ) {
4 |
5 | grunt.registerTask('rewriteMarkdownFiles', function() {
6 | var content = grunt.file.read('README.md');
7 | var overviewText = content.slice(content.indexOf('## Overview'), content.indexOf("## What's new"));
8 | content = content.replace('![The-M-Project Absinthe][logo]', '');
9 | content = content.replace(overviewText, '');
10 | grunt.file.write('doc-template/.tmp/index.md', content);
11 | });
12 | }
--------------------------------------------------------------------------------
/tasks/tpl/templates.txt:
--------------------------------------------------------------------------------
1 | // Copyright (c) 2014 M-Way Solutions GmbH
2 | // http://github.com/mwaylabs/The-M-Project/blob/absinthe/MIT-LICENSE.txt
3 |
4 | ////////////////////////////////////////////////////////////////
5 | // DO NOT EDIT THIS FILE - it is generated by grunt
6 | ////////////////////////////////////////////////////////////////
7 |
8 | /* jshint -W109 */
9 | M.Templates = [%= vars %];
10 | /* jshint +W109 */
--------------------------------------------------------------------------------
/tasks/tpl/themevars.txt:
--------------------------------------------------------------------------------
1 | // Copyright (c) 2014 M-Way Solutions GmbH
2 | // http://github.com/mwaylabs/The-M-Project/blob/absinthe/MIT-LICENSE.txt
3 |
4 | ////////////////////////////////////////////////////////////////
5 | // DO NOT EDIT THIS FILE - it is generated by grunt
6 | ////////////////////////////////////////////////////////////////
7 |
8 | M.ThemeVars = {
9 | _vars: <%= vars %>,
10 | get: function (name, theme) {
11 | var theme = theme || M.Environment.device.os;
12 |
13 | var result = this._vars[theme] ? this._vars[theme][name] : false;
14 | if (!result && theme != M.ThemeVars.CONST.DEFAULT) {
15 | result = this._vars[M.ThemeVars.CONST.DEFAULT][name];
16 | }
17 | if (!result) {
18 | console.log('Can not find varibale "' + name + '".');
19 | }
20 | return result;
21 | }
22 | }
23 |
24 | M.ThemeVars.CONST = {
25 | IOS: 'ios',
26 | ANDROID_DARK: 'android_dark',
27 | ANDROID_LIGHT: 'android_light',
28 | ANDROID: 'android_dark',
29 | DEFAULT: 'default'
30 | }
--------------------------------------------------------------------------------
/test/core/test.controller.js:
--------------------------------------------------------------------------------
1 | describe('M.Controller', function () {
2 |
3 | var instance;
4 |
5 | it('basic', function () {
6 | assert.isDefined(M.Controller);
7 | assert.isDefined(M.Controller.design);
8 | assert.isDefined(M.Controller.create);
9 | assert.isDefined(M.Controller.extend);
10 |
11 | assert.isFunction(M.Controller.design);
12 | assert.isFunction(M.Controller.create);
13 | assert.isFunction(M.Controller.extend);
14 |
15 | instance = M.Controller.create();
16 | assert.isDefined(instance);
17 | assert.isObject(instance);
18 | assert.isDefined(instance._type);
19 | assert.isString(instance._type);
20 | assert.equal(instance._type, 'M.Controller');
21 | });
22 |
23 | it('methods', function () {
24 | assert.isDefined(instance.set);
25 | assert.isDefined(instance.get);
26 | assert.isDefined(instance.show);
27 | assert.isDefined(instance.applicationStart);
28 | assert.isDefined(instance.on);
29 | assert.isDefined(instance.off);
30 | assert.isDefined(instance.trigger);
31 | assert.isDefined(instance.apply);
32 |
33 | assert.isFunction(instance.set);
34 | assert.isFunction(instance.get);
35 | assert.isFunction(instance.show);
36 | assert.isFunction(instance.applicationStart);
37 | assert.isFunction(instance.on);
38 | assert.isFunction(instance.off);
39 | assert.isFunction(instance.trigger);
40 | assert.isFunction(instance.apply);
41 | });
42 |
43 | it('set value', function() {
44 | instance.set('a','b');
45 | assert.equal(instance.a, 'b');
46 | }) ;
47 |
48 | it('get value', function() {
49 | assert.equal(instance.get('a'), 'b');
50 | })
51 |
52 | });
53 |
--------------------------------------------------------------------------------
/test/core/test.i18n_item.js:
--------------------------------------------------------------------------------
1 | describe('M.I18NItem', function () {
2 |
3 | it('M.I18NItem', function () {
4 |
5 | // Basic
6 | assert.isDefined(M.I18NItem);
7 | assert.isDefined(M.I18NItem._type);
8 |
9 | assert.isObject(M.I18NItem);
10 | assert.isString(M.I18NItem._type);
11 | assert.equal(M.I18NItem._type, 'M.I18NItem');
12 |
13 | // METHODS
14 | assert.isDefined(M.I18NItem.create);
15 |
16 | assert.isFunction(M.I18NItem.create);
17 |
18 | // PROPERTIES
19 | assert.isDefined(M.I18NItem.key);
20 | assert.isDefined(M.I18NItem.placeholder);
21 |
22 | assert.isNull(M.I18NItem.key);
23 | assert.isNull(M.I18NItem.placeholder);
24 |
25 | // CALLS
26 | var testItem1 = M.I18NItem.create('test.key');
27 | assert.equal(testItem1.key, 'test.key');
28 | assert.isNull(testItem1.placeholder);
29 |
30 | var testItem2 = M.I18NItem.create('test.key {{name}}', {name: 'Tom'});
31 | assert.equal(testItem2.key, 'test.key {{name}}');
32 | assert.isObject(testItem2.placeholder);
33 | assert.equal(testItem2.placeholder.name, 'Tom');
34 |
35 | var testItem3 = M.I18NItem.create();
36 | assert.isNull(testItem3);
37 | });
38 |
39 | });
40 |
--------------------------------------------------------------------------------
/test/core/test.object.js:
--------------------------------------------------------------------------------
1 | describe('M.Object', function () {
2 |
3 | it('basic', function () {
4 | assert.isDefined(M.Object);
5 | assert.isDefined(M.Object._type);
6 |
7 | assert.isObject(M.Object);
8 | assert.isString(M.Object._type);
9 | assert.equal(M.Object._type, 'M.Object');
10 | });
11 |
12 | it('properties', function () {
13 | assert.isDefined(M.Object._implementedInterfaces);
14 |
15 | assert.isNull(M.Object._implementedInterfaces);
16 | });
17 |
18 | it('methods', function () {
19 | assert.isDefined(M.Object._create);
20 | assert.isDefined(M.Object.include);
21 | assert.isDefined(M.Object.design);
22 | assert.isDefined(M.Object.implement);
23 | assert.isDefined(M.Object.hasInterfaceImplementation);
24 | assert.isDefined(M.Object._create);
25 | assert.isDefined(M.Object.bindToCaller);
26 | assert.isDefined(M.Object._init);
27 | assert.isDefined(M.Object._normalize);
28 | assert.isDefined(M.Object.handleCallback);
29 | assert.isDefined(M.Object.getObjectType);
30 |
31 | assert.isFunction(M.Object._create);
32 | assert.isFunction(M.Object.include);
33 | assert.isFunction(M.Object.design);
34 | assert.isFunction(M.Object.implement);
35 | assert.isFunction(M.Object.hasInterfaceImplementation);
36 | assert.isFunction(M.Object.bindToCaller);
37 | assert.isFunction(M.Object._init);
38 | assert.isFunction(M.Object._normalize);
39 | assert.isFunction(M.Object.handleCallback);
40 | assert.isFunction(M.Object.getObjectType);
41 |
42 | });
43 |
44 | it('implement function: _implementedInterfaces are not different for instances', function () {
45 |
46 | var testInterface = M.Interface.design({
47 | _type: 'test',
48 | getInterface: function() {
49 | return {
50 | testinterfaceImplementation: 'testinterfaceImplementation'
51 | };
52 | }
53 | });
54 | var TestView = M.View.extend().implements([testInterface]);
55 | var v1 = TestView.create();
56 | var interfaceCountV1 = v1._implementedInterfaces.length;
57 | var v2 = TestView.create();
58 | var interfaceCountV2 = v2._implementedInterfaces.length;
59 | assert.equal(interfaceCountV1, interfaceCountV2);
60 | assert.equal(v1._implementedInterfaces[interfaceCountV1], v2._implementedInterfaces[interfaceCountV2]);
61 |
62 | });
63 |
64 | });
65 |
--------------------------------------------------------------------------------
/test/core/test.router.js:
--------------------------------------------------------------------------------
1 | describe('M.Router', function () {
2 |
3 | var instance;
4 |
5 | it('basic', function () {
6 | assert.isDefined(M.Router);
7 | assert.isDefined(M.Router.design);
8 | assert.isDefined(M.Router.create);
9 | assert.isDefined(M.Router.extend);
10 |
11 | assert.isFunction(M.Router.design);
12 | assert.isFunction(M.Router.create);
13 | assert.isFunction(M.Router.extend);
14 |
15 | instance = M.Router.create();
16 | assert.isDefined(instance);
17 | assert.isObject(instance);
18 | assert.isDefined(instance._type);
19 | assert.isString(instance._type);
20 | assert.equal(instance._type, 'M.Router');
21 | });
22 |
23 | });
--------------------------------------------------------------------------------
/test/core/test.scope.js:
--------------------------------------------------------------------------------
1 | describe('Scope', function () {
2 |
3 | var instance;
4 |
5 | it.skip('scope via parameter', function () {
6 |
7 | var VAL = 'testproperty';
8 |
9 | var scope = {
10 | test: M.Model.create({
11 | prop: VAL
12 | })
13 | };
14 |
15 | var testView = M.View.extend({scopeKey: 'test.prop' }).create(scope, null, true).render();
16 | assert.equal(testView.getValue, VAL);
17 | assert.equal(testView.$el.find('[data-binding="value"]').html(), VAL);
18 |
19 | });
20 |
21 | it('scope via controller', function () {
22 |
23 | var VAL = 'testproperty';
24 |
25 | var scope = M.Controller.extend({
26 | test: M.Model.create({
27 | prop: VAL
28 | })
29 | }).create();
30 |
31 | var TestView = M.View.extend({scopeKey: 'test.prop' });
32 | var view = TestView.create(scope).render();
33 | assert.equal(view.getValue(), VAL);
34 | assert.equal(view.$el.find('[data-binding="value"]').html(), VAL);
35 |
36 | });
37 | });
38 |
--------------------------------------------------------------------------------
/test/data/test.entity.js:
--------------------------------------------------------------------------------
1 | describe('M.Entity', function() {
2 |
3 | var TEST = {
4 | fields: {
5 | id: { type: M.CONST.TYPE.STRING, required: YES, index: YES },
6 | sureName: { name: 'USERNAME', type: M.CONST.TYPE.STRING, required: YES, index: YES },
7 | firstName: { type: M.CONST.TYPE.STRING, length: 200 },
8 | age: M.CONST.TYPE.INTEGER,
9 | birthday: M.CONST.TYPE.DATE
10 | }
11 | }
12 |
13 | TEST.attributes = {
14 | id: 1000,
15 | sureName: 'Nachname',
16 | firstName: 'Vorname',
17 | age: '33',
18 | birthday: '1999-09-23'
19 | }
20 |
21 | it('creating an entity', function() {
22 | var entity = M.Entity.design({
23 | fields: TEST.fields
24 | });
25 | assert.isObject(entity, 'entity successfully created.');
26 | TEST.entity = entity;
27 |
28 | var id = entity.fields.id;
29 | assert.isObject(id, 'id field successfully created.');
30 | assert.equal(id.type, TEST.fields.id.type, 'id field has correct type.');
31 | assert.ok(id.required, 'id field is required.');
32 | assert.ok(id.index, 'id field is index.');
33 |
34 | var sureName = entity.fields.sureName;
35 | assert.isObject(sureName, 'sureName field successfully created.');
36 | assert.equal(sureName.type, TEST.fields.sureName.type, 'sureName field has correct type.');
37 | assert.ok(sureName.required, 'sureName field is required.');
38 | assert.ok(sureName.index, 'sureName field is index.');
39 |
40 | var firstName = entity.fields.firstName;
41 | assert.isObject(firstName, 'firstName field successfully created.');
42 | assert.equal(firstName.type, TEST.fields.firstName.type, 'firstName field has correct type.');
43 | assert.ok(!firstName.required, 'firstName field is not required.');
44 | assert.ok(!firstName.index, 'firstName field is not index.');
45 |
46 | var age = entity.fields.age;
47 | assert.isObject(age, 'age field successfully created.');
48 | assert.equal(age.type, TEST.fields.age, 'age field has correct type.');
49 | assert.ok(!age.required, 'age field is not required.');
50 | assert.ok(!age.index, 'age field is not index.');
51 |
52 | var birthday = entity.fields.birthday;
53 | assert.isObject(birthday, 'birthday field successfully created.');
54 | assert.equal(birthday.type, TEST.fields.birthday, 'birthday field has correct type.');
55 | assert.ok(!birthday.required, 'birthday field is not required.');
56 | assert.ok(!birthday.index, 'birthday field is not index.');
57 |
58 | });
59 |
60 | it('transform attributes to data', function() {
61 | TEST.data = TEST.entity.fromAttributes(TEST.attributes);
62 | assert.isString(TEST.data.id, 'id has the correct type');
63 | assert.equal(TEST.data.id, TEST.attributes.id + '', 'id holds the correct data');
64 | assert.isString(TEST.data.USERNAME, 'USERNAME has the correct type');
65 | assert.equal(TEST.data.USERNAME, TEST.attributes.sureName, 'USERNAME (sureName) holds the correct data');
66 | assert.isString(TEST.data.firstName, 'sureName has the correct type');
67 | assert.equal(TEST.data.firstName, TEST.attributes.firstName, 'firstName holds the correct data');
68 | assert.isNumber(TEST.data.age, 'age has the correct type');
69 | assert.equal(TEST.data.age, parseInt(TEST.attributes.age), 'firstName holds the correct data');
70 | assert.isObject(TEST.data.birthday, 'birthday has the correct type');
71 | assert.equal(TEST.data.birthday.format('YYYY-MM-DD'), TEST.attributes.birthday, 'birthday holds the correct data');
72 | });
73 |
74 | });
75 |
--------------------------------------------------------------------------------
/test/data/test.field.js:
--------------------------------------------------------------------------------
1 | describe('M.Field', function() {
2 |
3 | var TEST = {
4 | fields: {
5 | _id: { type: M.CONST.TYPE.STRING, required: YES, index: YES },
6 | sureName: { name: 'USERNAME', type: M.CONST.TYPE.STRING, required: YES, index: YES },
7 | firstName: { type: M.CONST.TYPE.STRING, length: 200 },
8 | age: M.CONST.TYPE.INTEGER,
9 | birthday: M.CONST.TYPE.DATE
10 | }
11 | }
12 |
13 | it('creating a field', function() {
14 | var id = M.Field.create( TEST.fields._id );
15 | assert.isObject(id, 'id field successfully created.');
16 | assert.equal(id.type, TEST.fields._id.type, 'id field has correct type.');
17 | assert.ok(id.required, 'id field is required.');
18 | assert.ok(id.index, 'id field is index.');
19 | TEST.id = id;
20 |
21 | var sureName = M.Field.create( TEST.fields.sureName );
22 | assert.isObject(sureName, 'sureName field successfully created.');
23 | assert.equal(sureName.type, TEST.fields.sureName.type, 'sureName field has correct type.');
24 | assert.ok(sureName.required, 'sureName field is required.');
25 | assert.ok(sureName.index, 'sureName field is index.');
26 | TEST.sureName = sureName;
27 |
28 | var firstName = M.Field.create( TEST.fields.firstName );
29 | assert.isObject(firstName, 'firstName field successfully created.');
30 | assert.equal(firstName.type, TEST.fields.firstName.type, 'firstName field has correct type.');
31 | assert.ok(!firstName.required, 'firstName field is not required.');
32 | assert.ok(!firstName.index, 'firstName field is not index.');
33 | TEST.firstName = firstName;
34 |
35 | var age = M.Field.create( TEST.fields.age );
36 | assert.isObject(age, 'age field successfully created.');
37 | assert.equal(age.type, TEST.fields.age, 'age field has correct type.');
38 | assert.ok(!age.required, 'age field is not required.');
39 | assert.ok(!age.index, 'age field is not index.');
40 | TEST.age = age;
41 |
42 | var birthday = M.Field.create( TEST.fields.birthday);
43 | assert.isObject(birthday, 'birthday field successfully created.');
44 | assert.equal(birthday.type, TEST.fields.birthday, 'birthday field has correct type.');
45 | assert.ok(!birthday.required, 'birthday field is not required.');
46 | assert.ok(!birthday.index, 'birthday field is not index.');
47 | TEST.birthday = birthday;
48 |
49 | });
50 |
51 | it('converting a field', function() {
52 | var value = TEST.sureName.transform(1000);
53 | assert.isString(value, 'sureName transforms integer into string');
54 |
55 | value = TEST.age.transform('23');
56 | assert.isNumber(value, 'age transforms string into integer');
57 |
58 | value = TEST.birthday.transform('2013-11-22');
59 | assert.isObject(value, 'birthday transforms string into date');
60 |
61 | });
62 |
63 | it('comparing a field', function() {
64 |
65 | assert.ok(TEST.sureName.equals(1000, '1000'), '1000 == "1000" for field type string')
66 |
67 | assert.ok(!TEST.age.equals(1000, '1002'), '1000 != "1002" for field type integer')
68 |
69 | assert.ok(TEST.age.equals(1000, '1000'), '1000 == "1000" for field type integer')
70 |
71 | assert.ok(TEST.age.equals(10.4, '10.7'), '10.4 == "10.7" for field type integer')
72 |
73 | });
74 |
75 | });
76 |
--------------------------------------------------------------------------------
/test/data/test.model.js:
--------------------------------------------------------------------------------
1 | describe('M.Model', function() {
2 |
3 | var TEST = {};
4 |
5 | it('basic', function () {
6 | assert.isDefined(M.Model);
7 | assert.isDefined(M.Model.design);
8 | assert.isDefined(M.Model.create);
9 | assert.isDefined(M.Model.extend);
10 |
11 | assert.isFunction(M.Model.design);
12 | assert.isFunction(M.Model.create);
13 | assert.isFunction(M.Model.extend);
14 |
15 | var instance = M.Model.create();
16 | assert.isDefined(instance);
17 | assert.isObject(instance);
18 | assert.isDefined(instance._type);
19 | assert.isString(instance._type);
20 | assert.equal(instance._type, 'M.Model');
21 | });
22 |
23 | it ('creating model', function() {
24 |
25 | assert.typeOf(M.Model, 'function', 'M.Model is defined.');
26 |
27 | var Person = M.Model.extend({
28 | idAttribute: 'id',
29 | defaults: { bmi: 0.0 },
30 | entity: {
31 | name: 'person',
32 | fields: {
33 | id: { type: M.CONST.TYPE.INTEGER, required: YES },
34 | firstName: { type: M.CONST.TYPE.STRING, length: 200 },
35 | sureName: { type: M.CONST.TYPE.STRING, required: YES, index: true },
36 | birthDate: { type: M.CONST.TYPE.DATE },
37 | bmi: { type: M.CONST.TYPE.FLOAT },
38 | notes: { type: M.CONST.TYPE.TEXT },
39 | address: { type: M.CONST.TYPE.OBJECT },
40 | displayName: { type: M.CONST.TYPE.STRING, persistent: NO }
41 | }
42 | }
43 | });
44 |
45 | assert.typeOf(Person, 'function', 'person model could be extended.');
46 |
47 | TEST.Person = Person.create();
48 |
49 | assert.typeOf(TEST.Person, 'object', 'empty person model could be created.');
50 |
51 | var p = Person.create({
52 | firstName: 'Max',
53 | sureName: 'Mustermann',
54 | birthDate: M.Date.create('01.02.2003'),
55 | notes: 'Notes to this person',
56 | address: { street: 'Leitzstraße', house_nr: 45, zip: '70469', city: 'Stuttgart' }
57 | });
58 |
59 | assert.ok(typeof p === 'object', 'person record could be created.');
60 |
61 | assert.ok(p.get('firstName') === 'Max', 'Field "firstName" is set.');
62 |
63 | assert.ok(p.get('sureName') === 'Mustermann', 'Field "sureName" is set.');
64 |
65 | assert.ok(p.get('bmi') === 0.0, 'Field "bmi" has correct default value.');
66 |
67 | assert.ok(p.get('notes') === 'Notes to this person', 'Field "note" has correct value.');
68 |
69 | assert.ok(typeof p.get('id') === 'undefined', 'Field "id" is undefined, as expected.');
70 |
71 | assert.ok(p.get('address').street === 'Leitzstraße', 'Field "address" has correct value.');
72 |
73 | });
74 |
75 | });
--------------------------------------------------------------------------------
/test/i18n/de.js:
--------------------------------------------------------------------------------
1 | {
2 | "global.button": {
3 | "save": "Dokument speichern",
4 | "emptyTrash": "Papierkorb leeren ({{count}})"
5 | }
6 | }
--------------------------------------------------------------------------------
/test/i18n/en.js:
--------------------------------------------------------------------------------
1 | {
2 | "global.button": {
3 | "save": "Save document",
4 | "emptyTrash": "Empty Trash ({{count}})"
5 | }
6 | }
--------------------------------------------------------------------------------
/test/interfaces/test.addcssclass.js:
--------------------------------------------------------------------------------
1 | describe.skip('M.AddCssClass implementation', function() {
2 |
3 | var general = function( testInterface ) {
4 | assert.isTrue(testInterface._type === 'M.Interface');
5 | assert.isDefined(testInterface.isMInterface);
6 | assert.isTrue(testInterface.isMInterface);
7 | assert.isFunction(testInterface.getInterface);
8 | }
9 |
10 | it('general', function() {
11 | general(M.Interface);
12 | assert.equal(M.AddCssClass._type, 'M.AddCssClass');
13 | });
14 |
15 | it('css classes', function() {
16 | var testView = M.View.extend({
17 | icon: 'search left'
18 | }).implements([M.IconBackground]).create().render();
19 | assert.isTrue(testView.$el.hasClass('view'));
20 | assert.isTrue(testView.$el.hasClass('search'));
21 | assert.isTrue(testView.$el.hasClass('left'));
22 | assert.isFalse(testView.$el.hasClass('null'));
23 |
24 | var testView = M.View.extend({}).implements([M.IconBackground]).create().render();
25 | assert.isTrue(testView.$el.hasClass('view'));
26 | assert.isFalse(testView.$el.hasClass('search'));
27 | assert.isFalse(testView.$el.hasClass('left'));
28 | assert.isFalse(testView.$el.hasClass('null'));
29 |
30 | var testView = M.View.extend({
31 | icon: 'search left',
32 | cssClass: 'a'
33 | }).implements([M.IconBackground]).create().render();
34 | assert.isTrue(testView.$el.hasClass('view'));
35 | assert.isTrue(testView.$el.hasClass('a'));
36 | assert.isTrue(testView.$el.hasClass('search'));
37 | assert.isTrue(testView.$el.hasClass('left'));
38 | assert.isFalse(testView.$el.hasClass('null'));
39 |
40 | var testView = M.View.extend({
41 | icon: 'search left',
42 | cssClass: 'a b'
43 | }).implements([M.IconBackground]).create().render();
44 | assert.isTrue(testView.$el.hasClass('view'));
45 | assert.isTrue(testView.$el.hasClass('a'));
46 | assert.isTrue(testView.$el.hasClass('b'));
47 | assert.isTrue(testView.$el.hasClass('search'));
48 | assert.isTrue(testView.$el.hasClass('left'));
49 | assert.isFalse(testView.$el.hasClass('null'));
50 |
51 | var testView = M.View.extend({
52 | icon: 'search left',
53 | cssClass: 'a b',
54 | _internalCssClasses: 'c d'
55 | }).implements([M.IconBackground]).create().render();
56 | assert.isTrue(testView.$el.hasClass('view'));
57 | assert.isTrue(testView.$el.hasClass('a'));
58 | assert.isTrue(testView.$el.hasClass('b'));
59 | assert.isTrue(testView.$el.hasClass('c'));
60 | assert.isTrue(testView.$el.hasClass('d'));
61 | assert.isTrue(testView.$el.hasClass('search'));
62 | assert.isTrue(testView.$el.hasClass('left'));
63 | assert.isFalse(testView.$el.hasClass('null'));
64 |
65 | var testView = M.View.extend({
66 | icon: 'search left',
67 | cssClass: 'a b',
68 | _internalCssClasses: 'c d',
69 | grid: 'e'
70 | }).implements([M.IconBackground]).create().render();
71 | assert.isTrue(testView.$el.hasClass('view'));
72 | assert.isTrue(testView.$el.hasClass('a'));
73 | assert.isTrue(testView.$el.hasClass('b'));
74 | assert.isTrue(testView.$el.hasClass('c'));
75 | assert.isTrue(testView.$el.hasClass('d'));
76 | assert.isTrue(testView.$el.hasClass('e'));
77 | assert.isTrue(testView.$el.hasClass('search'));
78 | assert.isTrue(testView.$el.hasClass('left'));
79 | assert.isFalse(testView.$el.hasClass('null'));
80 |
81 | testView = null;
82 | });
83 |
84 | });
85 |
--------------------------------------------------------------------------------
/test/js/bridge.js:
--------------------------------------------------------------------------------
1 | /*
2 | * Is injected into the spec runner file
3 |
4 | * Copyright (c) 2012 Kelly Miyashiro
5 | * Copyright (c) 2012 "Cowboy" Ben Alman
6 | * Licensed under the MIT license.
7 | * http://benalman.com/about/license/
8 | */
9 |
10 | /*global mocha:true, alert:true, window:true */
11 |
12 | (function() {
13 | // Send messages to the parent phantom.js process via alert! Good times!!
14 | function sendMessage() {
15 | var args = [].slice.call(arguments);
16 | alert(JSON.stringify(args));
17 | }
18 |
19 | // Create a listener who'll bubble events from Phantomjs to Grunt
20 | function createGruntListener(ev, runner) {
21 |
22 | runner.on(ev, function(test, err) {
23 | var data = {
24 | err: err
25 | };
26 |
27 | if (test) {
28 | data.title = test.title;
29 | data.fullTitle = test.fullTitle();
30 | data.duration = test.duration;
31 | data.slow = test.slow;
32 | }
33 |
34 | sendMessage('mocha.' + ev, data);
35 |
36 | });
37 | }
38 |
39 | var GruntReporter = function(runner){
40 | // 1.4.2 moved reporters to Mocha instead of mocha
41 | var mochaInstance = window.Mocha || window.mocha;
42 |
43 | if (!mochaInstance) {
44 | throw new Error('Mocha was not found, make sure you include Mocha in your HTML spec file.');
45 | }
46 |
47 | // Setup HTML reporter to output data on the screen
48 | mochaInstance.reporters.HTML.call(this, runner);
49 |
50 | // Create a Grunt listener for each Mocha events
51 | var events = [
52 | 'start',
53 | 'test',
54 | 'test end',
55 | 'suite',
56 | 'suite end',
57 | 'fail',
58 | 'pass',
59 | 'pending',
60 | 'end'
61 | ];
62 |
63 | for(var i = 0; i < events.length; i++) {
64 | createGruntListener(events[i], runner);
65 | }
66 |
67 | };
68 |
69 | var options = window.PHANTOMJS;
70 | if (options) {
71 | // Default mocha options
72 | var config = {
73 | ui: 'bdd',
74 | ignoreLeaks: true,
75 | reporter: GruntReporter
76 | },
77 | run = options.run,
78 | key;
79 |
80 | if (options) {
81 | // If options is a string, assume it is to set the UI (bdd/tdd etc)
82 | if (typeof options === "string") {
83 | config.ui = options;
84 | } else {
85 | // Extend defaults with passed options
86 | for (key in options.mocha) {
87 | config[key] = options.mocha[key];
88 | }
89 | }
90 | }
91 |
92 | config.reporter = GruntReporter;
93 |
94 | mocha.setup(config);
95 |
96 | // task option `run`, automatically runs mocha for grunt only
97 | if (run) {
98 | mocha.run();
99 | }
100 | }
101 | }());
102 |
--------------------------------------------------------------------------------
/test/test.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
Mocha Tests
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
--------------------------------------------------------------------------------
/test/test.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Dependencies.
3 | */
4 |
5 | if ('undefined' != typeof require) {
6 | chai = require('chai');
7 | assert = chai.assert;
8 | expect = chai.expect;
9 | }
10 |
11 | describe('Mocha', function() {
12 |
13 | it('assert samples', function() {
14 | var x = {};
15 | assert.valueOf(x, 'object', 'x is an object.');
16 | assert.isObject(x, 'x is an object.');
17 | assert.ok(1 !== 2, '1 is not 2');
18 | assert.equal(-1, [1,2,3].indexOf(5));
19 | assert.equal(-1, [1,2,3].indexOf(0));
20 | });
21 |
22 | it('expect samples', function() {
23 | var foo = 'bar'
24 | var beverages = { tea: [ 'chai', 'matcha', 'oolong' ] };
25 | expect(foo).to.be.a('string');
26 | expect(foo).to.equal('bar');
27 | expect(foo).to.have.length(3);
28 | expect(beverages).to.have.property('tea').with.length(3);
29 |
30 | });
31 | });
--------------------------------------------------------------------------------
/test/ui/binding/test.kitchensink.js:
--------------------------------------------------------------------------------
1 | describe('Model change example', function() {
2 |
3 | var TEST_ATTRIBUTE_1 = 'TEST_ATTRIBUTE_1';
4 | var TEST_ATTRIBUTE_2 = 'TEST_ATTRIBUTE_2';
5 | var TEST_ATTRIBUTE_3 = 'TEST_ATTRIBUTE_3';
6 | var TEST_ATTRIBUTE_4 = 'TEST_ATTRIBUTE_4';
7 |
8 | var getTestApplication = function() {
9 |
10 | var ParentView = M.View.extend({}, {
11 | bindingTestInput: M.View.extend({
12 | scopeKey: 'bindingTestModel',
13 | template: '
'
14 | }),
15 |
16 | bindingTestOutput: M.View.extend({
17 | scopeKey: 'bindingTestModel',
18 | template: '
'
19 | }),
20 |
21 | bindingTestAttributeA: M.View.extend({
22 | scopeKey: 'bindingTestModel.a'
23 | }),
24 |
25 | bindingTestAttributeB: M.View.extend({
26 | scopeKey: 'bindingTestModel.b'
27 | }),
28 |
29 | bindingTestAttributeTextfield: M.TextfieldView.extend({
30 | scopeKey: 'bindingTestModel.a'
31 | })
32 | });
33 |
34 | var bindingTestModel = M.Model.create({
35 | a: TEST_ATTRIBUTE_1,
36 | b: TEST_ATTRIBUTE_2
37 | });
38 |
39 | var scope = M.Controller.extend({
40 | bindingTestModel: bindingTestModel
41 | }).create();
42 |
43 | var testView = ParentView.create(scope, null, true);
44 |
45 | var contentBinding1 = testView.childViews.bindingTestInput;
46 | var contentBinding2 = testView.childViews.bindingTestOutput;
47 |
48 | var stickitA = testView.childViews.bindingTestAttributeA;
49 | var stickitB = testView.childViews.bindingTestAttributeB;
50 |
51 | var bindingTestAttributeTextfield = testView.childViews.bindingTestAttributeTextfield;
52 |
53 | return {
54 | view: testView,
55 | controller: scope,
56 | model: bindingTestModel,
57 | childViews: {
58 | contentBinding1: contentBinding1,
59 | contentBinding2: contentBinding2,
60 | stickitA: stickitA,
61 | stickitB: stickitB,
62 | bindingTestAttributeTextfield: bindingTestAttributeTextfield
63 | }
64 | }
65 |
66 | };
67 |
68 |
69 | it('', function() {
70 | var app = getTestApplication();
71 | checkProperties(app);
72 | app.view.render();
73 | checkProperties(app);
74 | var newModel = M.Model.create({a: TEST_ATTRIBUTE_3, b: TEST_ATTRIBUTE_4});
75 | app.controller.set('bindingTestModel', newModel);
76 | checkPropertiesAfter(app);
77 | });
78 |
79 |
80 | });
81 |
--------------------------------------------------------------------------------
/test/ui/events/test.events.tap.js:
--------------------------------------------------------------------------------
1 | describe('Tap Events', function () {
2 |
3 | it('Tap with render', function (done) {
4 |
5 | var elem = M.View.extend({
6 | events: {
7 | tap: function(event, element){
8 | done();
9 | }
10 | }
11 | }).create();
12 | elem.render();
13 | elem._hammertime.trigger('tap', {});
14 | });
15 |
16 | it('Tap without render', function (done) {
17 |
18 | var elem = M.View.extend({
19 | events: {
20 | tap: function(event, element){
21 | done();
22 | }
23 | }
24 | }).create();
25 | elem._hammertime.trigger('tap', {});
26 | });
27 |
28 | it('Tap with render and useElement set to YES', function (done) {
29 |
30 | var elem = M.View.extend({
31 | useElement: YES,
32 | events: {
33 | tap: function(event, element){
34 | done();
35 | }
36 | }
37 | }).create();
38 | elem.render();
39 | elem._hammertime.trigger('tap', {});
40 | });
41 |
42 | it('Event is bound to the correct dom element', function () {
43 |
44 | var elem = M.View.extend({
45 | useElement: YES,
46 | events: {
47 | tap: function(event, element){
48 |
49 | }
50 | }
51 | }).create();
52 | var before = elem.el;
53 | elem.render();
54 | assert.isTrue(elem._hammertime.element === elem.el);
55 | });
56 |
57 | it('Tap without render and useElement set to YES -> _hammertime should be undefined', function () {
58 |
59 | var elem = M.View.extend({
60 | useElement: YES,
61 | events: {
62 | tap: function(event, element){
63 |
64 | }
65 | }
66 | }).create();
67 |
68 | assert.isNull(elem._hammertime);
69 | });
70 |
71 | it('Tap a function from the scope', function (done) {
72 |
73 | var elem = M.View.extend({
74 | events: {
75 | tap: 'scopefunction'
76 | }
77 | }).create({
78 | scopefunction: function(){
79 | done();
80 | }
81 | }, null, true);
82 |
83 | elem._hammertime.trigger('tap', {});
84 | });
85 |
86 | it('Tap a function from the scope with render call', function (done) {
87 |
88 | var elem = M.View.extend({
89 | events: {
90 | tap: 'scopefunction'
91 | }
92 | }).create({
93 | scopefunction: function(){
94 | done();
95 | }
96 | }, null, true).render();
97 |
98 | elem._hammertime.trigger('tap', {});
99 | });
100 |
101 | it('Tap a function from the scope with useElement', function (done) {
102 |
103 | var elem = M.View.extend({
104 | useElement: YES,
105 | events: {
106 | tap: 'scopefunction'
107 | }
108 | }).create({
109 | scopefunction: function(){
110 | done();
111 | }
112 | }, null, true).render();
113 |
114 | elem._hammertime.trigger('tap', {});
115 | });
116 | });
117 |
--------------------------------------------------------------------------------
/test/ui/test.themevars.js:
--------------------------------------------------------------------------------
1 | describe('M.PageTransitions', function () {
2 |
3 |
4 | it('basic', function () {
5 | assert.isDefined(M.ThemeVars);
6 | assert.isObject(M.ThemeVars);
7 | assert.isFunction(M.ThemeVars.get);
8 | assert.isDefined(M.ThemeVars._vars);
9 | assert.isObject(M.ThemeVars._vars);
10 | });
11 |
12 | it('check theme names', function () {
13 | assert.isDefined(M.ThemeVars._vars.default);
14 | assert.isObject(M.ThemeVars._vars.default);
15 |
16 | assert.isDefined(M.ThemeVars._vars.android_dark);
17 | assert.isObject(M.ThemeVars._vars.android_dark);
18 |
19 | assert.isDefined(M.ThemeVars._vars.android_light);
20 | assert.isObject(M.ThemeVars._vars.android_light);
21 |
22 | assert.isDefined(M.ThemeVars._vars.ios);
23 | assert.isObject(M.ThemeVars._vars.ios);
24 | });
25 |
26 |
27 | it('get variables', function () {
28 | var themeVars = JSON.stringify(M.ThemeVars._vars);
29 | M.ThemeVars._vars = {
30 | default: {
31 | "colorA": "#AAA",
32 | "colorB": "#BBB"
33 | },
34 | ios: {
35 | colorB: '#BABABA',
36 | colorC: '#CCC'
37 | }
38 | }
39 |
40 | assert.equal(M.ThemeVars.get('colorA'), '#AAA');
41 | assert.equal(M.ThemeVars.get('colorB'), '#BBB');
42 | assert.isUndefined(M.ThemeVars.get('colorC'));
43 |
44 | assert.equal(M.ThemeVars.get('colorA', 'ios'), '#AAA');
45 | assert.equal(M.ThemeVars.get('colorB', 'ios'), '#BABABA');
46 | assert.equal(M.ThemeVars.get('colorC', 'ios'), '#CCC');
47 | M.ThemeVars._vars = JSON.parse(themeVars);
48 | });
49 |
50 | it('theme vars', function(){
51 | assert.isDefined(M.ThemeVars, '1');
52 | assert.isFunction(M.ThemeVars.get, '2');
53 | assert.isDefined(M.ThemeVars._vars, '3');
54 | assert.isDefined(M.ThemeVars._vars.default, '4');
55 |
56 | assert.isDefined(M.ThemeVars._vars.default['m-menu-view-width'], JSON.stringify(M.ThemeVars._vars.default));
57 | assert.equal(M.ThemeVars._vars.default['m-menu-view-width'], M.ThemeVars.get('m-menu-view-width', 'default'), '6');
58 | assert.equal(M.ThemeVars._vars.default['m-menu-view-width'], M.ThemeVars.get('m-menu-view-width'), '7');
59 | });
60 | });
61 |
--------------------------------------------------------------------------------
/test/ui/views/test.button.js:
--------------------------------------------------------------------------------
1 | describe('M.Button', function () {
2 |
3 | it('general', function () {
4 |
5 | // Basic
6 | assert.isDefined(M.ButtonView);
7 | assert.isFunction(M.ButtonView);
8 | assert.isTrue(M.View.prototype.isPrototypeOf(M.ButtonView.create()));
9 |
10 | });
11 |
12 | });
13 |
--------------------------------------------------------------------------------
/test/ui/views/test.image.js:
--------------------------------------------------------------------------------
1 | describe('M.ImageView', function () {
2 |
3 | it('general', function () {
4 |
5 | // Basic
6 | assert.isDefined(M.ImageView);
7 | assert.isFunction(M.ImageView);
8 | assert.isTrue(M.View.prototype.isPrototypeOf(M.ImageView.create()));
9 |
10 |
11 | });
12 |
13 | it('instance simple with default parameters', function () {
14 | var testView = M.ImageView.create();
15 | assert.equal(testView._type, 'M.ImageView');
16 |
17 | assert.isDefined(testView.alt);
18 | assert.equal(testView.alt, '');
19 |
20 | assert.isDefined(testView._template);
21 | assert.isString(testView._templateString);
22 |
23 | testView = null;
24 |
25 | });
26 |
27 | it('instance simple with all parameters', function () {
28 | var ALT = '1234ABCD';
29 | var GRID = 'abcdEFGH1234LMNO';
30 | var VALUE = 'ASDFKjfdklajkjsfdlökjgk';
31 |
32 | var testView = M.ImageView.extend({
33 | value: VALUE,
34 | alt: ALT,
35 | grid: GRID
36 |
37 | }).create().render();
38 |
39 | assert.isDefined(testView._type);
40 | assert.equal(testView._type, 'M.ImageView');
41 |
42 | assert.isDefined(testView.grid);
43 | assert.equal(testView.grid, GRID);
44 | assert.isTrue(testView.$el.hasClass(GRID));
45 |
46 | assert.isDefined(testView.value);
47 | assert.equal(testView.value, VALUE);
48 | assert.equal(testView.$el.find('img').attr('src'), VALUE);
49 |
50 | assert.isDefined(testView.alt);
51 | assert.equal(testView.alt, ALT);
52 | assert.equal(testView.$el.find('img').attr('alt'), ALT);
53 |
54 | assert.isDefined(testView._template);
55 | assert.isFunction(testView._template);
56 |
57 | testView = null;
58 | var ALT = null;
59 | var GRID = null;
60 | var VALUE = null;
61 |
62 | });
63 |
64 | it('_assignTemplateValues', function () {
65 | var testView = M.ImageView.extend({}).create().render();
66 |
67 | var test = function (testText) {
68 | testView._setValue(testText);
69 | testView.alt = testText;
70 |
71 | testView._assignTemplateValues();
72 |
73 | assert.equal(testView._templateValues.alt, testText);
74 | assert.equal(testView.getValue(), testText);
75 |
76 | };
77 | test('asdf');
78 | test('');
79 | test([]);
80 | test({});
81 | test(1);
82 |
83 | testView = null;
84 | test = null;
85 |
86 | });
87 |
88 | it('initialize', function(){
89 |
90 | var testView = null;
91 |
92 | var test = function (testText) {
93 | testView = M.ImageView.extend({
94 | value:'',
95 | alt: testText
96 | }).create();
97 |
98 | testView.initialize();
99 | if(testText === null){
100 | assert.equal(testView.alt, '')
101 | }
102 | else{
103 | assert.equal(testView.alt, testText);
104 | }
105 | };
106 |
107 | test('asdf');
108 | test('');
109 | test([]);
110 | test({});
111 | test(1);
112 | test(null);
113 |
114 | testView = null;
115 | test = null;
116 | });
117 |
118 | });
119 |
--------------------------------------------------------------------------------
/test/ui/views/test.searchfield.js:
--------------------------------------------------------------------------------
1 | describe.skip('M.SearchfieldView', function () {
2 |
3 | it('general', function () {
4 |
5 | // Basic
6 | assert.isDefined(M.SearchfieldView);
7 | assert.isFunction(M.SearchfieldView);
8 | assert.isTrue(M.View.prototype.isPrototypeOf(M.SearchfieldView.create()));
9 |
10 | });
11 |
12 | it('instance simple with default parameters', function () {
13 | var testView = M.SearchfieldView.create();
14 |
15 | assert.isDefined(testView._type);
16 | assert.equal(testView._type, 'M.SearchfieldView');
17 |
18 | assert.isDefined(testView.placeholder);
19 | assert.equal(testView.placeholder, 'Search');
20 |
21 | assert.isDefined(testView._template);
22 | assert.isFunction(testView._template);
23 |
24 | testView = null;
25 |
26 | });
27 |
28 | it('instance simple with all parameters', function () {
29 | /**
30 | * Test noch nicht fertig
31 | */
32 | var GRID = 'abcdEFGH1234LMNO';
33 | var VALUE = 'ASDFKjfdklajkjsfdlökjgk';
34 | var LABEL = 'ASDHAHFöklnhjuznqpomfdakjf';
35 | var PLACEHOLDER = 'qwerertzASDFFGHJTZbvn';
36 |
37 | var testView = M.SearchfieldView.extend({
38 | grid: GRID,
39 | label: LABEL,
40 | value: VALUE,
41 | placeholder: PLACEHOLDER
42 | }).create().render();
43 |
44 | assert.isDefined(testView._type);
45 | assert.equal(testView._type, 'M.SearchfieldView');
46 |
47 | assert.isDefined(testView.grid);
48 | assert.equal(testView.grid, GRID);
49 | assert.isTrue(testView.$el.hasClass(GRID));
50 |
51 | assert.isDefined(testView.placeholder);
52 | assert.equal(testView.placeholder, PLACEHOLDER);
53 |
54 | assert.isDefined(testView.label);
55 | assert.equal(testView.label, LABEL);
56 |
57 | assert.isDefined(testView.getValue());
58 | assert.equal(testView.getValue(), VALUE);
59 |
60 | assert.isDefined(testView._template);
61 | assert.isFunction(testView._template);
62 |
63 | testView = null;
64 |
65 | var GRID = null;
66 | var VALUE = null;
67 | var LABEL = null;
68 | var PLACEHOLDER = null;
69 |
70 | });
71 |
72 | });
73 |
--------------------------------------------------------------------------------
/test/ui/views/test.template.js:
--------------------------------------------------------------------------------
1 | describe.skip ('M.View Templates', function() {
2 |
3 | it('data binding', function() {
4 |
5 | var testView = M.View.extend().create({value: 'asdf'}).render();
6 | assert.lengthOf(testView.$el.find('[data-binding="value"]'), 0);
7 |
8 | var testView = M.View.extend().create({value:M.Model.create({value: 'asdf'})}).render();
9 | assert.lengthOf(testView.$el.find('[data-binding="value"]'), 1);
10 |
11 | });
12 |
13 |
14 | });
15 |
--------------------------------------------------------------------------------
/test/ui/views/test.toast.js:
--------------------------------------------------------------------------------
1 | describe('M.Toast', function () {
2 |
3 | it('general', function () {
4 |
5 | // Basic
6 | assert.isDefined(M.Toast);
7 | assert.isFunction(M.Toast);
8 | assert.isFunction(M.Toast.show);
9 | assert.isTrue(Backbone.View.prototype.isPrototypeOf(M.Toast.create()));
10 | assert.isTrue(M.Toast.CONST.RAW === 500);
11 | assert.isTrue(M.Toast.CONST.MEDIUM === 2000);
12 | assert.isTrue(M.Toast.CONST.CRISPY === 4000);
13 | assert.isTrue(M.Toast.CONST.TEXT === '');
14 |
15 | var toast = M.Toast.create();
16 |
17 | assert.isDefined(toast);
18 | var id = _.uniqueId();
19 | assert.isTrue(toast.id === (id-1).toString());
20 | assert.isTrue(toast.text === M.Toast.CONST.TEXT);
21 |
22 | var toast = M.Toast.create({
23 | text: 'test'
24 | });
25 |
26 | assert.isTrue(toast.text === 'test');
27 |
28 | });
29 |
30 | it('M.Toast static', function(){
31 | $('body').find('.toastview .toast div').remove();
32 | M.Toast.show('test');
33 | assert.equal($('body').find('.toastview .toast div').text(), 'test');
34 | });
35 |
36 | it('M.Toast timeout MEDIUM', function( done ){
37 | this.timeout(M.Toast.CONST.MEDIUM + 500);
38 | M.Toast.removeAll();
39 | M.Toast.show('test');
40 |
41 | console.log(M.Toast._stack.length, $('body').find('.toastview .toast div').text());
42 |
43 | assert.equal($('body').find('.toastview .toast div').text(), 'test');
44 | setTimeout(function(){
45 | assert.lengthOf($('body').find('.toastview .toast div'), 0);
46 | done();
47 | }, M.Toast.CONST.MEDIUM);
48 | });
49 | });
50 |
--------------------------------------------------------------------------------
/test/ui/views/test.toolbar.js:
--------------------------------------------------------------------------------
1 | describe('M.ToolbarView', function() {
2 |
3 | it('general', function() {
4 |
5 | // Basic
6 | assert.isDefined(M.ToolbarView);
7 | assert.isFunction(M.ToolbarView);
8 | assert.isTrue(M.View.prototype.isPrototypeOf(M.ToolbarView.create()));
9 |
10 | var toolbarTemplate = M.TemplateManager.get('toolbar.ejs');
11 |
12 | var regex = /data-childviews="first"/gi;
13 | var test = regex.exec(toolbarTemplate)
14 | assert.isTrue(test.length === 1, toolbarTemplate);
15 |
16 | regex = /data-childviews="second"/gi;
17 | assert.isTrue(regex.exec(toolbarTemplate).length === 1);
18 | });
19 | });
20 |
--------------------------------------------------------------------------------
/test/ui/views/test.view.computedvalue.js:
--------------------------------------------------------------------------------
1 | describe.skip('Computed value', function () {
2 |
3 | it('basic', function () {
4 |
5 | var testview = M.View.create();
6 | assert.isNull(testview.computedValue);
7 |
8 | var testview = M.View.create({
9 | value: 'A',
10 | computedValue: function( val ) {
11 | return val + 'B'
12 | }});
13 | assert.isDefined(testview.computedValue);
14 | assert.isFunction(testview.computedValue);
15 |
16 | testview.render();
17 | assert.equal(testview.getV,'AB');
18 |
19 |
20 |
21 |
22 | });
23 |
24 | });
25 |
--------------------------------------------------------------------------------
/thanks_to.md:
--------------------------------------------------------------------------------
1 | # Technologie:
2 |
3 | ## html5
4 |
5 |
6 | ## javascript
7 |
8 |
9 | ## css3
10 |
11 |
12 |
13 | # Core:
14 |
15 | ## Backbone
16 |
17 |
18 | ## jQuery mobile:
19 |
20 |
21 | ## Topcoat:
22 |
23 |
24 | ## Bootstrap:
25 |
26 |
27 | ## Hammer:
28 |
29 |
30 | ## stickit
31 |
32 |
33 |
34 | # Build Tool:
35 |
36 | ## Grunt:
37 |
38 |
39 | ## Bower:
40 |
41 |
42 | ## Yeoman:
43 |
44 |
45 | ## node
46 |
47 |
48 |
49 | # Libraties
50 |
51 | ## modernizr
52 |
53 |
54 |
55 | # Tools
56 |
57 | ## github
58 |
59 |
60 | ## webstorm
61 |
62 |
63 | # Platforms
64 |
65 | ## android
66 |
67 |
68 |
69 |
70 | ## ios
71 | ????
72 |
73 | ## blackberry
74 |
75 | ## windows phone
76 |
77 | # Company
78 |
79 | ## M-Way
80 |
81 |
82 |
83 | # Links
84 | http://backbonejs.org/
85 | http://underscorejs.org/
86 | http://jquery.com
87 | http://getbootstrap.com/
88 | http://eightmedia.github.io/hammer.js/
89 | http://nytimes.github.io/backbone.stickit/
90 | http://socket.io/
91 | http://modernizr.com/
92 | http://momentjs.com/
93 | https://github.com/barisaydinoglu/Detectizr
94 | http://fontawesome.io/
95 | https://github.com/alexgibson/shake.js/
96 | https://github.com/ftlabs/fastclick
97 | https://github.com/mwaylabs/grunt-tmpl
98 | https://github.com/mwaylabs/tmpl
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 |
109 |
110 |
111 |
112 |
113 |
114 |
115 |
--------------------------------------------------------------------------------