├── .eslintrc
├── .gitignore
├── .travis.yml
├── app
├── css
│ ├── app.css
│ ├── normalize.css
│ └── unsemantic-grid-responsive.css
├── index.html
├── js
│ ├── app.js
│ ├── controller
│ │ ├── edit_todo.js
│ │ ├── footer.js
│ │ ├── imprint.js
│ │ ├── index.js
│ │ ├── todo.js
│ │ └── todo_list.js
│ └── service
│ │ ├── imprint.js
│ │ ├── index.js
│ │ └── todos.js
└── views
│ ├── imprint.html
│ └── todos.html
├── bin
├── browserify.sh
├── start-selenium.sh
└── watchify.sh
├── gulpfile.js
├── karma.conf.js
├── karma.conf.js.travis
├── package.json
├── protractor.conf.js
├── protractor.conf.js.travis
├── readme.markdown
└── test
├── browserified
├── .gitignore
└── index.html
├── e2e
├── delete_todo_spec.js
├── edit_todo_spec.js
├── list_todo_spec.js
├── new_todo_spec.js
├── pages
│ └── todo_page.js
└── select_todo_spec.js
├── mocha.opts
└── unit
├── controller
├── edit_todo.js
└── todo_list.js
└── service
├── imprint.js
└── todos.js
/.eslintrc:
--------------------------------------------------------------------------------
1 | {
2 | "env": {
3 | "browser": true,
4 | "mocha": true,
5 | "node": true,
6 | "amd": false
7 | },
8 | "rules": {
9 | "no-alert": 2,
10 | "no-array-constructor": 2,
11 | "no-bitwise": 0,
12 | "no-caller": 2,
13 | "no-catch-shadow": 2,
14 | "no-comma-dangle": 0,
15 | "no-cond-assign": 2,
16 | "no-console": 2,
17 | "no-constant-condition": 2,
18 | "no-control-regex": 2,
19 | "no-debugger": 2,
20 | "no-delete-var": 2,
21 | "no-div-regex": 0,
22 | "no-dupe-keys": 2,
23 | "no-else-return": 0,
24 | "no-empty": 2,
25 | "no-empty-character-class": 2,
26 | "no-empty-label": 2,
27 | "no-eq-null": 0,
28 | "no-eval": 2,
29 | "no-ex-assign": 2,
30 | "no-extend-native": 2,
31 | "no-extra-boolean-cast": 2,
32 | "no-extra-parens": 0,
33 | "no-extra-semi": 2,
34 | "no-fallthrough": 2,
35 | "no-floating-decimal": 0,
36 | "no-func-assign": 2,
37 | "no-global-strict": 0,
38 | "no-implied-eval": 2,
39 | "no-invalid-regexp": 2,
40 | "no-iterator": 2,
41 | "no-label-var": 2,
42 | "no-labels": 2,
43 | "no-lone-blocks": 2,
44 | "no-lonely-if": 0,
45 | "no-loop-func": 2,
46 | "no-mixed-requires": [0, false],
47 | "no-multi-str": 2,
48 | "no-native-reassign": 2,
49 | "no-negated-in-lhs": 2,
50 | "no-nested-ternary": 0,
51 | "no-new": 2,
52 | "no-new-func": 2,
53 | "no-new-object": 2,
54 | "no-new-require": 0,
55 | "no-new-wrappers": 2,
56 | "no-obj-calls": 2,
57 | "no-octal": 2,
58 | "no-octal-escape": 2,
59 | "no-path-concat": 0,
60 | "no-plusplus": 0,
61 | "no-process-exit": 2,
62 | "no-proto": 2,
63 | "no-redeclare": 2,
64 | "no-regex-spaces": 2,
65 | "no-restricted-modules": 0,
66 | "no-return-assign": 2,
67 | "no-script-url": 2,
68 | "no-self-compare": 0,
69 | "no-sequences": 2,
70 | "no-shadow": 2,
71 | "no-shadow-restricted-names": 2,
72 | "no-spaced-func": 2,
73 | "semi-spacing": 2,
74 | "no-sparse-arrays": 2,
75 | "no-sync": 0,
76 | "no-ternary": 0,
77 | "no-undef": 2,
78 | "no-undef-init": 2,
79 | "no-underscore-dangle": 2,
80 | "no-unreachable": 2,
81 | "no-unused-expressions": 0,
82 | "no-unused-vars": [2, {"vars": "local", "args": "after-used"}],
83 | "no-use-before-define": 0,
84 | "no-warning-comments": [0, { "terms": ["todo", "fixme", "xxx"], "location": "start" }],
85 | "no-with": 2,
86 | "no-extra-parens": 2,
87 | "yoda": [2, "never"],
88 |
89 | "block-scoped-var": 0,
90 | "brace-style": [0, "1tbs"],
91 | "camelcase": 2,
92 | "complexity": [0, 11],
93 | "consistent-return": 2,
94 | "consistent-this": [0, "that"],
95 | "curly": [2, "all"],
96 | "default-case": 0,
97 | "dot-notation": 2,
98 | "eqeqeq": 2,
99 | "func-names": 0,
100 | "func-style": [0, "declaration"],
101 | "guard-for-in": 0,
102 | "max-depth": [0, 4],
103 | "max-len": [0, 80, 4],
104 | "max-nested-callbacks": [0, 2],
105 | "max-params": [0, 3],
106 | "max-statements": [0, 10],
107 | "handle-callback-err": 0,
108 | "new-cap": 0,
109 | "new-parens": 2,
110 | "one-var": 0,
111 | "quote-props": 0,
112 | "quotes": [2, "single"],
113 | "radix": 0,
114 | "semi": 2,
115 | "sort-vars": 0,
116 | "space-after-keywords": [0, "always"],
117 | "space-in-brackets": [0, "never"],
118 | "space-infix-ops": 2,
119 | "space-return-throw-case": 2,
120 | "space-unary-word-ops": 0,
121 | "strict": [2, "global"],
122 | "use-isnan": 2,
123 | "valid-jsdoc": 0,
124 | "valid-typeof": 2,
125 | "wrap-iife": 0,
126 | "wrap-regex": 0
127 | },
128 | "globals": {
129 | "browser": true,
130 | "by": true,
131 | "element": true,
132 | "expect": true,
133 | "protractor": true,
134 | "xdescribe": true,
135 | "xit": true
136 | }
137 | }
138 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | node_modules
2 |
3 | # vim tmp files
4 | *.swp
5 | *.un~
6 |
7 | app/ngmin
8 | app/ngAnnotate
9 | app/dist
10 |
--------------------------------------------------------------------------------
/.travis.yml:
--------------------------------------------------------------------------------
1 | ---
2 | language: node_js
3 | node_js:
4 | - '4'
5 | - '5'
6 |
7 | before_script:
8 | - npm install -g phantomjs@1.9.8
9 | - cp protractor.conf.js.travis protractor.conf.js
10 | - cp karma.conf.js.travis karma.conf.js
11 | - export DISPLAY=:99.0
12 | - sh -e /etc/init.d/xvfb start
13 |
--------------------------------------------------------------------------------
/app/css/app.css:
--------------------------------------------------------------------------------
1 | body {
2 | background-color: #ddd;
3 | font: 14px "Lucida Grande", Helvetica, Arial, sans-serif;
4 | padding: 20px;
5 | }
6 |
7 | img {
8 | vertical-align: middle;
9 | }
10 |
11 | input {
12 | font: inherit;
13 | font-family: inherit;
14 | margin: 0;
15 | }
16 |
17 | .content {
18 | max-width: 960px;
19 | }
20 |
21 | .span-save {
22 | text-decoration: none;
23 | vertical-align: middle;
24 | }
25 |
26 | .margins {
27 | margin-top: 2px;
28 | margin-bottom: 3px;
29 | margin-left: 3px;
30 | margin-right: 3px;
31 | }
32 |
33 | .padding {
34 | padding-top: 2px;
35 | padding-bottom: 2px;
36 | padding-left: 7px;
37 | padding-top: 2px;
38 | }
39 |
40 | .rounded-box {
41 | border-width: 0px;
42 | border-radius: 4px;
43 | }
44 |
45 | button {
46 | margin: 0em;
47 | font: -webkit-small-control;
48 | color: initial;
49 | letter-spacing: normal;
50 | word-spacing: normal;
51 | text-transform: none;
52 | text-indent: 0px;
53 | text-shadow: none;
54 | display: inline-block;
55 | text-align: start;
56 | }
57 |
58 | .btn {
59 | display: inline-block;
60 | font-weight: normal;
61 | text-align: center;
62 | vertical-align: middle;
63 | cursor: pointer;
64 | background-image: none;
65 | border: 1px solid ;
66 | white-space: nowrap;
67 | padding: 6px 12px;
68 | font-size: 14px;
69 | line-height: 1.42857143;
70 | border-radius: 4px;
71 | -webkit-user-select: none;
72 | -moz-user-select: none;
73 | -ms-user-select: none;
74 | user-select: none;
75 | color: #ccc;
76 | background-color: #203040;
77 | border-color: #102030;
78 | }
79 |
80 | .btn:hover, .btn:focus, .btn:active {
81 | color: #fff;
82 | border-color: #102030;
83 | background-color: #506070;
84 | }
85 |
86 | .dark-blue-bg {
87 | background-color: #203040;
88 | }
89 |
90 | .medium-blue-bg {
91 | background-color: #304050;
92 | }
93 |
94 | .text-on-blue {
95 | color: #ccc;
96 | }
97 |
98 | .sidebar-heading {
99 | border-top-left-radius: 4px;
100 | border-top-right-radius: 4px;
101 | padding-top: 7px;
102 | padding-bottom: 7px;
103 | padding-left: 7px;
104 | font-size: 1.3em;
105 | }
106 |
107 | .sidebar-heading-skin {
108 | border-bottom-style: solid;
109 | border-bottom-width: 1px;
110 | border-bottom-color: #071720;
111 | }
112 |
113 | .sidebar-item-borders {
114 | color: inherit;
115 | border-top-width: 1px;
116 | border-top-style: solid;
117 | border-top-color: #304050;
118 | border-bottom-width: 1px;
119 | border-bottom-style: solid;
120 | border-bottom-color: #071720;
121 | border-right-width: 0px;
122 | border-left-width: 0px;
123 | }
124 |
125 | .sidebar-item-borders:last-child {
126 | border-bottom-width: 0px;
127 | border-bottom-left-radius: 4px;
128 | border-bottom-right-radius: 4px;
129 | }
130 |
131 | .sidebar-item {
132 | display: block;
133 | padding: 5px 15px;
134 | position: relative;
135 | color: inherit;
136 | text-decoration: inherit;
137 | }
138 |
139 | .sidebar-item-inactive {
140 | cursor: pointer;
141 | }
142 |
143 | /* highlight hovered item a bit... */
144 | a:hover.sidebar-item {
145 | color: #eee;
146 | text-decoration: inherit;
147 | }
148 | /* ...but not if it is already selected */
149 | a:hover.sidebar-item-active {
150 | color: inherit;
151 | text-decoration: inherit;
152 | }
153 |
154 | /* needs to be defined after sidebar-item */
155 | .sidebar-item-active {
156 | font-weight: bold;
157 | border-top-color: #031017;
158 | border-bottom-color: #203040;
159 | background-image: none;
160 | background-color: #102030;
161 | cursor: default;
162 | }
163 |
164 | /* in headline */
165 | .current-item {
166 | font-size: 18px;
167 | font-weight: bold;
168 | height: 28px;
169 | line-height: 36px;
170 | }
171 |
172 | .current-item-edit {
173 | width: 80%;
174 | color: #333;
175 | line-height: 18px;
176 | }
177 |
178 | .todo-text {
179 | height: 200px;
180 | background-color: #eee;
181 | }
182 |
183 | .todo-text-edit {
184 | width: 97%;
185 | }
186 |
187 | .footer {
188 | font-size: small;
189 | width: 100%;
190 | text-align: center;
191 | }
192 |
--------------------------------------------------------------------------------
/app/css/normalize.css:
--------------------------------------------------------------------------------
1 | /*! normalize.css v3.0.0 | MIT License | git.io/normalize */
2 |
3 | /**
4 | * 1. Set default font family to sans-serif.
5 | * 2. Prevent iOS text size adjust after orientation change, without disabling
6 | * user zoom.
7 | */
8 |
9 | html {
10 | font-family: sans-serif; /* 1 */
11 | -ms-text-size-adjust: 100%; /* 2 */
12 | -webkit-text-size-adjust: 100%; /* 2 */
13 | }
14 |
15 | /**
16 | * Remove default margin.
17 | */
18 |
19 | body {
20 | margin: 0;
21 | }
22 |
23 | /* HTML5 display definitions
24 | ========================================================================== */
25 |
26 | /**
27 | * Correct `block` display not defined in IE 8/9.
28 | */
29 |
30 | article,
31 | aside,
32 | details,
33 | figcaption,
34 | figure,
35 | footer,
36 | header,
37 | hgroup,
38 | main,
39 | nav,
40 | section,
41 | summary {
42 | display: block;
43 | }
44 |
45 | /**
46 | * 1. Correct `inline-block` display not defined in IE 8/9.
47 | * 2. Normalize vertical alignment of `progress` in Chrome, Firefox, and Opera.
48 | */
49 |
50 | audio,
51 | canvas,
52 | progress,
53 | video {
54 | display: inline-block; /* 1 */
55 | vertical-align: baseline; /* 2 */
56 | }
57 |
58 | /**
59 | * Prevent modern browsers from displaying `audio` without controls.
60 | * Remove excess height in iOS 5 devices.
61 | */
62 |
63 | audio:not([controls]) {
64 | display: none;
65 | height: 0;
66 | }
67 |
68 | /**
69 | * Address `[hidden]` styling not present in IE 8/9.
70 | * Hide the `template` element in IE, Safari, and Firefox < 22.
71 | */
72 |
73 | [hidden],
74 | template {
75 | display: none;
76 | }
77 |
78 | /* Links
79 | ========================================================================== */
80 |
81 | /**
82 | * Remove the gray background color from active links in IE 10.
83 | */
84 |
85 | a {
86 | background: transparent;
87 | }
88 |
89 | /**
90 | * Improve readability when focused and also mouse hovered in all browsers.
91 | */
92 |
93 | a:active,
94 | a:hover {
95 | outline: 0;
96 | }
97 |
98 | /* Text-level semantics
99 | ========================================================================== */
100 |
101 | /**
102 | * Address styling not present in IE 8/9, Safari 5, and Chrome.
103 | */
104 |
105 | abbr[title] {
106 | border-bottom: 1px dotted;
107 | }
108 |
109 | /**
110 | * Address style set to `bolder` in Firefox 4+, Safari 5, and Chrome.
111 | */
112 |
113 | b,
114 | strong {
115 | font-weight: bold;
116 | }
117 |
118 | /**
119 | * Address styling not present in Safari 5 and Chrome.
120 | */
121 |
122 | dfn {
123 | font-style: italic;
124 | }
125 |
126 | /**
127 | * Address variable `h1` font-size and margin within `section` and `article`
128 | * contexts in Firefox 4+, Safari 5, and Chrome.
129 | */
130 |
131 | h1 {
132 | font-size: 2em;
133 | margin: 0.67em 0;
134 | }
135 |
136 | /**
137 | * Address styling not present in IE 8/9.
138 | */
139 |
140 | mark {
141 | background: #ff0;
142 | color: #000;
143 | }
144 |
145 | /**
146 | * Address inconsistent and variable font size in all browsers.
147 | */
148 |
149 | small {
150 | font-size: 80%;
151 | }
152 |
153 | /**
154 | * Prevent `sub` and `sup` affecting `line-height` in all browsers.
155 | */
156 |
157 | sub,
158 | sup {
159 | font-size: 75%;
160 | line-height: 0;
161 | position: relative;
162 | vertical-align: baseline;
163 | }
164 |
165 | sup {
166 | top: -0.5em;
167 | }
168 |
169 | sub {
170 | bottom: -0.25em;
171 | }
172 |
173 | /* Embedded content
174 | ========================================================================== */
175 |
176 | /**
177 | * Remove border when inside `a` element in IE 8/9.
178 | */
179 |
180 | img {
181 | border: 0;
182 | }
183 |
184 | /**
185 | * Correct overflow displayed oddly in IE 9.
186 | */
187 |
188 | svg:not(:root) {
189 | overflow: hidden;
190 | }
191 |
192 | /* Grouping content
193 | ========================================================================== */
194 |
195 | /**
196 | * Address margin not present in IE 8/9 and Safari 5.
197 | */
198 |
199 | figure {
200 | margin: 1em 40px;
201 | }
202 |
203 | /**
204 | * Address differences between Firefox and other browsers.
205 | */
206 |
207 | hr {
208 | -moz-box-sizing: content-box;
209 | box-sizing: content-box;
210 | height: 0;
211 | }
212 |
213 | /**
214 | * Contain overflow in all browsers.
215 | */
216 |
217 | pre {
218 | overflow: auto;
219 | }
220 |
221 | /**
222 | * Address odd `em`-unit font size rendering in all browsers.
223 | */
224 |
225 | code,
226 | kbd,
227 | pre,
228 | samp {
229 | font-family: monospace, monospace;
230 | font-size: 1em;
231 | }
232 |
233 | /* Forms
234 | ========================================================================== */
235 |
236 | /**
237 | * Known limitation: by default, Chrome and Safari on OS X allow very limited
238 | * styling of `select`, unless a `border` property is set.
239 | */
240 |
241 | /**
242 | * 1. Correct color not being inherited.
243 | * Known issue: affects color of disabled elements.
244 | * 2. Correct font properties not being inherited.
245 | * 3. Address margins set differently in Firefox 4+, Safari 5, and Chrome.
246 | */
247 |
248 | button,
249 | input,
250 | optgroup,
251 | select,
252 | textarea {
253 | color: inherit; /* 1 */
254 | font: inherit; /* 2 */
255 | margin: 0; /* 3 */
256 | }
257 |
258 | /**
259 | * Address `overflow` set to `hidden` in IE 8/9/10.
260 | */
261 |
262 | button {
263 | overflow: visible;
264 | }
265 |
266 | /**
267 | * Address inconsistent `text-transform` inheritance for `button` and `select`.
268 | * All other form control elements do not inherit `text-transform` values.
269 | * Correct `button` style inheritance in Firefox, IE 8+, and Opera
270 | * Correct `select` style inheritance in Firefox.
271 | */
272 |
273 | button,
274 | select {
275 | text-transform: none;
276 | }
277 |
278 | /**
279 | * 1. Avoid the WebKit bug in Android 4.0.* where (2) destroys native `audio`
280 | * and `video` controls.
281 | * 2. Correct inability to style clickable `input` types in iOS.
282 | * 3. Improve usability and consistency of cursor style between image-type
283 | * `input` and others.
284 | */
285 |
286 | button,
287 | html input[type="button"], /* 1 */
288 | input[type="reset"],
289 | input[type="submit"] {
290 | -webkit-appearance: button; /* 2 */
291 | cursor: pointer; /* 3 */
292 | }
293 |
294 | /**
295 | * Re-set default cursor for disabled elements.
296 | */
297 |
298 | button[disabled],
299 | html input[disabled] {
300 | cursor: default;
301 | }
302 |
303 | /**
304 | * Remove inner padding and border in Firefox 4+.
305 | */
306 |
307 | button::-moz-focus-inner,
308 | input::-moz-focus-inner {
309 | border: 0;
310 | padding: 0;
311 | }
312 |
313 | /**
314 | * Address Firefox 4+ setting `line-height` on `input` using `!important` in
315 | * the UA stylesheet.
316 | */
317 |
318 | input {
319 | line-height: normal;
320 | }
321 |
322 | /**
323 | * It's recommended that you don't attempt to style these elements.
324 | * Firefox's implementation doesn't respect box-sizing, padding, or width.
325 | *
326 | * 1. Address box sizing set to `content-box` in IE 8/9/10.
327 | * 2. Remove excess padding in IE 8/9/10.
328 | */
329 |
330 | input[type="checkbox"],
331 | input[type="radio"] {
332 | box-sizing: border-box; /* 1 */
333 | padding: 0; /* 2 */
334 | }
335 |
336 | /**
337 | * Fix the cursor style for Chrome's increment/decrement buttons. For certain
338 | * `font-size` values of the `input`, it causes the cursor style of the
339 | * decrement button to change from `default` to `text`.
340 | */
341 |
342 | input[type="number"]::-webkit-inner-spin-button,
343 | input[type="number"]::-webkit-outer-spin-button {
344 | height: auto;
345 | }
346 |
347 | /**
348 | * 1. Address `appearance` set to `searchfield` in Safari 5 and Chrome.
349 | * 2. Address `box-sizing` set to `border-box` in Safari 5 and Chrome
350 | * (include `-moz` to future-proof).
351 | */
352 |
353 | input[type="search"] {
354 | -webkit-appearance: textfield; /* 1 */
355 | -moz-box-sizing: content-box;
356 | -webkit-box-sizing: content-box; /* 2 */
357 | box-sizing: content-box;
358 | }
359 |
360 | /**
361 | * Remove inner padding and search cancel button in Safari and Chrome on OS X.
362 | * Safari (but not Chrome) clips the cancel button when the search input has
363 | * padding (and `textfield` appearance).
364 | */
365 |
366 | input[type="search"]::-webkit-search-cancel-button,
367 | input[type="search"]::-webkit-search-decoration {
368 | -webkit-appearance: none;
369 | }
370 |
371 | /**
372 | * Define consistent border, margin, and padding.
373 | */
374 |
375 | fieldset {
376 | border: 1px solid #c0c0c0;
377 | margin: 0 2px;
378 | padding: 0.35em 0.625em 0.75em;
379 | }
380 |
381 | /**
382 | * 1. Correct `color` not being inherited in IE 8/9.
383 | * 2. Remove padding so people aren't caught out if they zero out fieldsets.
384 | */
385 |
386 | legend {
387 | border: 0; /* 1 */
388 | padding: 0; /* 2 */
389 | }
390 |
391 | /**
392 | * Remove default vertical scrollbar in IE 8/9.
393 | */
394 |
395 | textarea {
396 | overflow: auto;
397 | }
398 |
399 | /**
400 | * Don't inherit the `font-weight` (applied by a rule above).
401 | * NOTE: the default cannot safely be changed in Chrome and Safari on OS X.
402 | */
403 |
404 | optgroup {
405 | font-weight: bold;
406 | }
407 |
408 | /* Tables
409 | ========================================================================== */
410 |
411 | /**
412 | * Remove most spacing between table cells.
413 | */
414 |
415 | table {
416 | border-collapse: collapse;
417 | border-spacing: 0;
418 | }
419 |
420 | td,
421 | th {
422 | padding: 0;
423 | }
424 |
--------------------------------------------------------------------------------
/app/css/unsemantic-grid-responsive.css:
--------------------------------------------------------------------------------
1 | /* ============================================ */
2 | /* This file has a mobile-to-desktop breakpoint */
3 | /* ============================================ */
4 | @media screen and (max-width: 400px) {
5 | @-ms-viewport {
6 | width: 320px;
7 | }
8 | }
9 | @media all {
10 | .clear {
11 | clear: both;
12 | display: block;
13 | overflow: hidden;
14 | visibility: hidden;
15 | width: 0;
16 | height: 0;
17 | }
18 |
19 | .grid-container:before, .clearfix:before,
20 | .grid-container:after,
21 | .clearfix:after {
22 | content: ".";
23 | display: block;
24 | overflow: hidden;
25 | visibility: hidden;
26 | font-size: 0;
27 | line-height: 0;
28 | width: 0;
29 | height: 0;
30 | }
31 |
32 | .grid-container:after, .clearfix:after {
33 | clear: both;
34 | }
35 |
36 | .grid-container, .clearfix {
37 | /* */
38 | *zoom: 1;
39 | /* */
40 | }
41 |
42 | .grid-container {
43 | margin-left: auto;
44 | margin-right: auto;
45 | max-width: 1200px;
46 | padding-left: 10px;
47 | padding-right: 10px;
48 | }
49 |
50 | .grid-5, .mobile-grid-5, .grid-10, .mobile-grid-10, .grid-15, .mobile-grid-15, .grid-20, .mobile-grid-20, .grid-25, .mobile-grid-25, .grid-30, .mobile-grid-30, .grid-35, .mobile-grid-35, .grid-40, .mobile-grid-40, .grid-45, .mobile-grid-45, .grid-50, .mobile-grid-50, .grid-55, .mobile-grid-55, .grid-60, .mobile-grid-60, .grid-65, .mobile-grid-65, .grid-70, .mobile-grid-70, .grid-75, .mobile-grid-75, .grid-80, .mobile-grid-80, .grid-85, .mobile-grid-85, .grid-90, .mobile-grid-90, .grid-95, .mobile-grid-95, .grid-100, .mobile-grid-100, .grid-33, .mobile-grid-33, .grid-66, .mobile-grid-66 {
51 | -webkit-box-sizing: border-box;
52 | -moz-box-sizing: border-box;
53 | box-sizing: border-box;
54 | padding-left: 10px;
55 | padding-right: 10px;
56 | /* */
57 | *padding-left: 0;
58 | *padding-right: 0;
59 | /* */
60 | }
61 | .grid-5 > *, .mobile-grid-5 > *, .grid-10 > *, .mobile-grid-10 > *, .grid-15 > *, .mobile-grid-15 > *, .grid-20 > *, .mobile-grid-20 > *, .grid-25 > *, .mobile-grid-25 > *, .grid-30 > *, .mobile-grid-30 > *, .grid-35 > *, .mobile-grid-35 > *, .grid-40 > *, .mobile-grid-40 > *, .grid-45 > *, .mobile-grid-45 > *, .grid-50 > *, .mobile-grid-50 > *, .grid-55 > *, .mobile-grid-55 > *, .grid-60 > *, .mobile-grid-60 > *, .grid-65 > *, .mobile-grid-65 > *, .grid-70 > *, .mobile-grid-70 > *, .grid-75 > *, .mobile-grid-75 > *, .grid-80 > *, .mobile-grid-80 > *, .grid-85 > *, .mobile-grid-85 > *, .grid-90 > *, .mobile-grid-90 > *, .grid-95 > *, .mobile-grid-95 > *, .grid-100 > *, .mobile-grid-100 > *, .grid-33 > *, .mobile-grid-33 > *, .grid-66 > *, .mobile-grid-66 > * {
62 | /* */
63 | *margin-left: expression((!this.className.match(/grid-[1-9]/) && this.currentStyle.display === "block" && this.currentStyle.width === "auto") && "10px");
64 | *margin-right: expression((!this.className.match(/grid-[1-9]/) && this.currentStyle.display === "block" && this.currentStyle.width === "auto") && "10px");
65 | /* */
66 | }
67 |
68 | .grid-parent {
69 | padding-left: 0;
70 | padding-right: 0;
71 | }
72 | }
73 | @media screen and (max-width: 767px) {
74 | .mobile-grid-100:before,
75 | .mobile-grid-100:after {
76 | content: ".";
77 | display: block;
78 | overflow: hidden;
79 | visibility: hidden;
80 | font-size: 0;
81 | line-height: 0;
82 | width: 0;
83 | height: 0;
84 | }
85 |
86 | .mobile-grid-100:after {
87 | clear: both;
88 | }
89 |
90 | .mobile-grid-100 {
91 | /* */
92 | *zoom: 1;
93 | /* */
94 | }
95 |
96 | .mobile-push-5,
97 | .mobile-pull-5, .mobile-push-10,
98 | .mobile-pull-10, .mobile-push-15,
99 | .mobile-pull-15, .mobile-push-20,
100 | .mobile-pull-20, .mobile-push-25,
101 | .mobile-pull-25, .mobile-push-30,
102 | .mobile-pull-30, .mobile-push-35,
103 | .mobile-pull-35, .mobile-push-40,
104 | .mobile-pull-40, .mobile-push-45,
105 | .mobile-pull-45, .mobile-push-50,
106 | .mobile-pull-50, .mobile-push-55,
107 | .mobile-pull-55, .mobile-push-60,
108 | .mobile-pull-60, .mobile-push-65,
109 | .mobile-pull-65, .mobile-push-70,
110 | .mobile-pull-70, .mobile-push-75,
111 | .mobile-pull-75, .mobile-push-80,
112 | .mobile-pull-80, .mobile-push-85,
113 | .mobile-pull-85, .mobile-push-90,
114 | .mobile-pull-90, .mobile-push-95,
115 | .mobile-pull-95, .mobile-push-33,
116 | .mobile-pull-33, .mobile-push-66,
117 | .mobile-pull-66 {
118 | position: relative;
119 | }
120 |
121 | .hide-on-mobile {
122 | display: none !important;
123 | }
124 |
125 | .mobile-grid-5 {
126 | float: left;
127 | width: 5%;
128 | /* */
129 | *width: expression(Math.floor(0.05 * (this.parentNode.offsetWidth - parseFloat(this.parentNode.currentStyle.paddingLeft) - parseFloat(this.parentNode.currentStyle.paddingRight))) + "px");
130 | /* */
131 | }
132 |
133 | .mobile-prefix-5 {
134 | margin-left: 5%;
135 | }
136 |
137 | .mobile-suffix-5 {
138 | margin-right: 5%;
139 | }
140 |
141 | .mobile-push-5 {
142 | left: 5%;
143 | /* */
144 | *left: expression(Math.floor(0.05 * (this.parentNode.offsetWidth - parseFloat(this.parentNode.currentStyle.paddingLeft) - parseFloat(this.parentNode.currentStyle.paddingRight))) + "px");
145 | /* */
146 | }
147 |
148 | .mobile-pull-5 {
149 | left: -5%;
150 | /* */
151 | *left: expression(Math.floor(-0.05 * (this.parentNode.offsetWidth - parseFloat(this.parentNode.currentStyle.paddingLeft) - parseFloat(this.parentNode.currentStyle.paddingRight))) + "px");
152 | /* */
153 | }
154 |
155 | .mobile-grid-10 {
156 | float: left;
157 | width: 10%;
158 | /* */
159 | *width: expression(Math.floor(0.1 * (this.parentNode.offsetWidth - parseFloat(this.parentNode.currentStyle.paddingLeft) - parseFloat(this.parentNode.currentStyle.paddingRight))) + "px");
160 | /* */
161 | }
162 |
163 | .mobile-prefix-10 {
164 | margin-left: 10%;
165 | }
166 |
167 | .mobile-suffix-10 {
168 | margin-right: 10%;
169 | }
170 |
171 | .mobile-push-10 {
172 | left: 10%;
173 | /* */
174 | *left: expression(Math.floor(0.1 * (this.parentNode.offsetWidth - parseFloat(this.parentNode.currentStyle.paddingLeft) - parseFloat(this.parentNode.currentStyle.paddingRight))) + "px");
175 | /* */
176 | }
177 |
178 | .mobile-pull-10 {
179 | left: -10%;
180 | /* */
181 | *left: expression(Math.floor(-0.1 * (this.parentNode.offsetWidth - parseFloat(this.parentNode.currentStyle.paddingLeft) - parseFloat(this.parentNode.currentStyle.paddingRight))) + "px");
182 | /* */
183 | }
184 |
185 | .mobile-grid-15 {
186 | float: left;
187 | width: 15%;
188 | /* */
189 | *width: expression(Math.floor(0.15 * (this.parentNode.offsetWidth - parseFloat(this.parentNode.currentStyle.paddingLeft) - parseFloat(this.parentNode.currentStyle.paddingRight))) + "px");
190 | /* */
191 | }
192 |
193 | .mobile-prefix-15 {
194 | margin-left: 15%;
195 | }
196 |
197 | .mobile-suffix-15 {
198 | margin-right: 15%;
199 | }
200 |
201 | .mobile-push-15 {
202 | left: 15%;
203 | /* */
204 | *left: expression(Math.floor(0.15 * (this.parentNode.offsetWidth - parseFloat(this.parentNode.currentStyle.paddingLeft) - parseFloat(this.parentNode.currentStyle.paddingRight))) + "px");
205 | /* */
206 | }
207 |
208 | .mobile-pull-15 {
209 | left: -15%;
210 | /* */
211 | *left: expression(Math.floor(-0.15 * (this.parentNode.offsetWidth - parseFloat(this.parentNode.currentStyle.paddingLeft) - parseFloat(this.parentNode.currentStyle.paddingRight))) + "px");
212 | /* */
213 | }
214 |
215 | .mobile-grid-20 {
216 | float: left;
217 | width: 20%;
218 | /* */
219 | *width: expression(Math.floor(0.2 * (this.parentNode.offsetWidth - parseFloat(this.parentNode.currentStyle.paddingLeft) - parseFloat(this.parentNode.currentStyle.paddingRight))) + "px");
220 | /* */
221 | }
222 |
223 | .mobile-prefix-20 {
224 | margin-left: 20%;
225 | }
226 |
227 | .mobile-suffix-20 {
228 | margin-right: 20%;
229 | }
230 |
231 | .mobile-push-20 {
232 | left: 20%;
233 | /* */
234 | *left: expression(Math.floor(0.2 * (this.parentNode.offsetWidth - parseFloat(this.parentNode.currentStyle.paddingLeft) - parseFloat(this.parentNode.currentStyle.paddingRight))) + "px");
235 | /* */
236 | }
237 |
238 | .mobile-pull-20 {
239 | left: -20%;
240 | /* */
241 | *left: expression(Math.floor(-0.2 * (this.parentNode.offsetWidth - parseFloat(this.parentNode.currentStyle.paddingLeft) - parseFloat(this.parentNode.currentStyle.paddingRight))) + "px");
242 | /* */
243 | }
244 |
245 | .mobile-grid-25 {
246 | float: left;
247 | width: 25%;
248 | /* */
249 | *width: expression(Math.floor(0.25 * (this.parentNode.offsetWidth - parseFloat(this.parentNode.currentStyle.paddingLeft) - parseFloat(this.parentNode.currentStyle.paddingRight))) + "px");
250 | /* */
251 | }
252 |
253 | .mobile-prefix-25 {
254 | margin-left: 25%;
255 | }
256 |
257 | .mobile-suffix-25 {
258 | margin-right: 25%;
259 | }
260 |
261 | .mobile-push-25 {
262 | left: 25%;
263 | /* */
264 | *left: expression(Math.floor(0.25 * (this.parentNode.offsetWidth - parseFloat(this.parentNode.currentStyle.paddingLeft) - parseFloat(this.parentNode.currentStyle.paddingRight))) + "px");
265 | /* */
266 | }
267 |
268 | .mobile-pull-25 {
269 | left: -25%;
270 | /* */
271 | *left: expression(Math.floor(-0.25 * (this.parentNode.offsetWidth - parseFloat(this.parentNode.currentStyle.paddingLeft) - parseFloat(this.parentNode.currentStyle.paddingRight))) + "px");
272 | /* */
273 | }
274 |
275 | .mobile-grid-30 {
276 | float: left;
277 | width: 30%;
278 | /* */
279 | *width: expression(Math.floor(0.3 * (this.parentNode.offsetWidth - parseFloat(this.parentNode.currentStyle.paddingLeft) - parseFloat(this.parentNode.currentStyle.paddingRight))) + "px");
280 | /* */
281 | }
282 |
283 | .mobile-prefix-30 {
284 | margin-left: 30%;
285 | }
286 |
287 | .mobile-suffix-30 {
288 | margin-right: 30%;
289 | }
290 |
291 | .mobile-push-30 {
292 | left: 30%;
293 | /* */
294 | *left: expression(Math.floor(0.3 * (this.parentNode.offsetWidth - parseFloat(this.parentNode.currentStyle.paddingLeft) - parseFloat(this.parentNode.currentStyle.paddingRight))) + "px");
295 | /* */
296 | }
297 |
298 | .mobile-pull-30 {
299 | left: -30%;
300 | /* */
301 | *left: expression(Math.floor(-0.3 * (this.parentNode.offsetWidth - parseFloat(this.parentNode.currentStyle.paddingLeft) - parseFloat(this.parentNode.currentStyle.paddingRight))) + "px");
302 | /* */
303 | }
304 |
305 | .mobile-grid-35 {
306 | float: left;
307 | width: 35%;
308 | /* */
309 | *width: expression(Math.floor(0.35 * (this.parentNode.offsetWidth - parseFloat(this.parentNode.currentStyle.paddingLeft) - parseFloat(this.parentNode.currentStyle.paddingRight))) + "px");
310 | /* */
311 | }
312 |
313 | .mobile-prefix-35 {
314 | margin-left: 35%;
315 | }
316 |
317 | .mobile-suffix-35 {
318 | margin-right: 35%;
319 | }
320 |
321 | .mobile-push-35 {
322 | left: 35%;
323 | /* */
324 | *left: expression(Math.floor(0.35 * (this.parentNode.offsetWidth - parseFloat(this.parentNode.currentStyle.paddingLeft) - parseFloat(this.parentNode.currentStyle.paddingRight))) + "px");
325 | /* */
326 | }
327 |
328 | .mobile-pull-35 {
329 | left: -35%;
330 | /* */
331 | *left: expression(Math.floor(-0.35 * (this.parentNode.offsetWidth - parseFloat(this.parentNode.currentStyle.paddingLeft) - parseFloat(this.parentNode.currentStyle.paddingRight))) + "px");
332 | /* */
333 | }
334 |
335 | .mobile-grid-40 {
336 | float: left;
337 | width: 40%;
338 | /* */
339 | *width: expression(Math.floor(0.4 * (this.parentNode.offsetWidth - parseFloat(this.parentNode.currentStyle.paddingLeft) - parseFloat(this.parentNode.currentStyle.paddingRight))) + "px");
340 | /* */
341 | }
342 |
343 | .mobile-prefix-40 {
344 | margin-left: 40%;
345 | }
346 |
347 | .mobile-suffix-40 {
348 | margin-right: 40%;
349 | }
350 |
351 | .mobile-push-40 {
352 | left: 40%;
353 | /* */
354 | *left: expression(Math.floor(0.4 * (this.parentNode.offsetWidth - parseFloat(this.parentNode.currentStyle.paddingLeft) - parseFloat(this.parentNode.currentStyle.paddingRight))) + "px");
355 | /* */
356 | }
357 |
358 | .mobile-pull-40 {
359 | left: -40%;
360 | /* */
361 | *left: expression(Math.floor(-0.4 * (this.parentNode.offsetWidth - parseFloat(this.parentNode.currentStyle.paddingLeft) - parseFloat(this.parentNode.currentStyle.paddingRight))) + "px");
362 | /* */
363 | }
364 |
365 | .mobile-grid-45 {
366 | float: left;
367 | width: 45%;
368 | /* */
369 | *width: expression(Math.floor(0.45 * (this.parentNode.offsetWidth - parseFloat(this.parentNode.currentStyle.paddingLeft) - parseFloat(this.parentNode.currentStyle.paddingRight))) + "px");
370 | /* */
371 | }
372 |
373 | .mobile-prefix-45 {
374 | margin-left: 45%;
375 | }
376 |
377 | .mobile-suffix-45 {
378 | margin-right: 45%;
379 | }
380 |
381 | .mobile-push-45 {
382 | left: 45%;
383 | /* */
384 | *left: expression(Math.floor(0.45 * (this.parentNode.offsetWidth - parseFloat(this.parentNode.currentStyle.paddingLeft) - parseFloat(this.parentNode.currentStyle.paddingRight))) + "px");
385 | /* */
386 | }
387 |
388 | .mobile-pull-45 {
389 | left: -45%;
390 | /* */
391 | *left: expression(Math.floor(-0.45 * (this.parentNode.offsetWidth - parseFloat(this.parentNode.currentStyle.paddingLeft) - parseFloat(this.parentNode.currentStyle.paddingRight))) + "px");
392 | /* */
393 | }
394 |
395 | .mobile-grid-50 {
396 | float: left;
397 | width: 50%;
398 | /* */
399 | *width: expression(Math.floor(0.5 * (this.parentNode.offsetWidth - parseFloat(this.parentNode.currentStyle.paddingLeft) - parseFloat(this.parentNode.currentStyle.paddingRight))) + "px");
400 | /* */
401 | }
402 |
403 | .mobile-prefix-50 {
404 | margin-left: 50%;
405 | }
406 |
407 | .mobile-suffix-50 {
408 | margin-right: 50%;
409 | }
410 |
411 | .mobile-push-50 {
412 | left: 50%;
413 | /* */
414 | *left: expression(Math.floor(0.5 * (this.parentNode.offsetWidth - parseFloat(this.parentNode.currentStyle.paddingLeft) - parseFloat(this.parentNode.currentStyle.paddingRight))) + "px");
415 | /* */
416 | }
417 |
418 | .mobile-pull-50 {
419 | left: -50%;
420 | /* */
421 | *left: expression(Math.floor(-0.5 * (this.parentNode.offsetWidth - parseFloat(this.parentNode.currentStyle.paddingLeft) - parseFloat(this.parentNode.currentStyle.paddingRight))) + "px");
422 | /* */
423 | }
424 |
425 | .mobile-grid-55 {
426 | float: left;
427 | width: 55%;
428 | /* */
429 | *width: expression(Math.floor(0.55 * (this.parentNode.offsetWidth - parseFloat(this.parentNode.currentStyle.paddingLeft) - parseFloat(this.parentNode.currentStyle.paddingRight))) + "px");
430 | /* */
431 | }
432 |
433 | .mobile-prefix-55 {
434 | margin-left: 55%;
435 | }
436 |
437 | .mobile-suffix-55 {
438 | margin-right: 55%;
439 | }
440 |
441 | .mobile-push-55 {
442 | left: 55%;
443 | /* */
444 | *left: expression(Math.floor(0.55 * (this.parentNode.offsetWidth - parseFloat(this.parentNode.currentStyle.paddingLeft) - parseFloat(this.parentNode.currentStyle.paddingRight))) + "px");
445 | /* */
446 | }
447 |
448 | .mobile-pull-55 {
449 | left: -55%;
450 | /* */
451 | *left: expression(Math.floor(-0.55 * (this.parentNode.offsetWidth - parseFloat(this.parentNode.currentStyle.paddingLeft) - parseFloat(this.parentNode.currentStyle.paddingRight))) + "px");
452 | /* */
453 | }
454 |
455 | .mobile-grid-60 {
456 | float: left;
457 | width: 60%;
458 | /* */
459 | *width: expression(Math.floor(0.6 * (this.parentNode.offsetWidth - parseFloat(this.parentNode.currentStyle.paddingLeft) - parseFloat(this.parentNode.currentStyle.paddingRight))) + "px");
460 | /* */
461 | }
462 |
463 | .mobile-prefix-60 {
464 | margin-left: 60%;
465 | }
466 |
467 | .mobile-suffix-60 {
468 | margin-right: 60%;
469 | }
470 |
471 | .mobile-push-60 {
472 | left: 60%;
473 | /* */
474 | *left: expression(Math.floor(0.6 * (this.parentNode.offsetWidth - parseFloat(this.parentNode.currentStyle.paddingLeft) - parseFloat(this.parentNode.currentStyle.paddingRight))) + "px");
475 | /* */
476 | }
477 |
478 | .mobile-pull-60 {
479 | left: -60%;
480 | /* */
481 | *left: expression(Math.floor(-0.6 * (this.parentNode.offsetWidth - parseFloat(this.parentNode.currentStyle.paddingLeft) - parseFloat(this.parentNode.currentStyle.paddingRight))) + "px");
482 | /* */
483 | }
484 |
485 | .mobile-grid-65 {
486 | float: left;
487 | width: 65%;
488 | /* */
489 | *width: expression(Math.floor(0.65 * (this.parentNode.offsetWidth - parseFloat(this.parentNode.currentStyle.paddingLeft) - parseFloat(this.parentNode.currentStyle.paddingRight))) + "px");
490 | /* */
491 | }
492 |
493 | .mobile-prefix-65 {
494 | margin-left: 65%;
495 | }
496 |
497 | .mobile-suffix-65 {
498 | margin-right: 65%;
499 | }
500 |
501 | .mobile-push-65 {
502 | left: 65%;
503 | /* */
504 | *left: expression(Math.floor(0.65 * (this.parentNode.offsetWidth - parseFloat(this.parentNode.currentStyle.paddingLeft) - parseFloat(this.parentNode.currentStyle.paddingRight))) + "px");
505 | /* */
506 | }
507 |
508 | .mobile-pull-65 {
509 | left: -65%;
510 | /* */
511 | *left: expression(Math.floor(-0.65 * (this.parentNode.offsetWidth - parseFloat(this.parentNode.currentStyle.paddingLeft) - parseFloat(this.parentNode.currentStyle.paddingRight))) + "px");
512 | /* */
513 | }
514 |
515 | .mobile-grid-70 {
516 | float: left;
517 | width: 70%;
518 | /* */
519 | *width: expression(Math.floor(0.7 * (this.parentNode.offsetWidth - parseFloat(this.parentNode.currentStyle.paddingLeft) - parseFloat(this.parentNode.currentStyle.paddingRight))) + "px");
520 | /* */
521 | }
522 |
523 | .mobile-prefix-70 {
524 | margin-left: 70%;
525 | }
526 |
527 | .mobile-suffix-70 {
528 | margin-right: 70%;
529 | }
530 |
531 | .mobile-push-70 {
532 | left: 70%;
533 | /* */
534 | *left: expression(Math.floor(0.7 * (this.parentNode.offsetWidth - parseFloat(this.parentNode.currentStyle.paddingLeft) - parseFloat(this.parentNode.currentStyle.paddingRight))) + "px");
535 | /* */
536 | }
537 |
538 | .mobile-pull-70 {
539 | left: -70%;
540 | /* */
541 | *left: expression(Math.floor(-0.7 * (this.parentNode.offsetWidth - parseFloat(this.parentNode.currentStyle.paddingLeft) - parseFloat(this.parentNode.currentStyle.paddingRight))) + "px");
542 | /* */
543 | }
544 |
545 | .mobile-grid-75 {
546 | float: left;
547 | width: 75%;
548 | /* */
549 | *width: expression(Math.floor(0.75 * (this.parentNode.offsetWidth - parseFloat(this.parentNode.currentStyle.paddingLeft) - parseFloat(this.parentNode.currentStyle.paddingRight))) + "px");
550 | /* */
551 | }
552 |
553 | .mobile-prefix-75 {
554 | margin-left: 75%;
555 | }
556 |
557 | .mobile-suffix-75 {
558 | margin-right: 75%;
559 | }
560 |
561 | .mobile-push-75 {
562 | left: 75%;
563 | /* */
564 | *left: expression(Math.floor(0.75 * (this.parentNode.offsetWidth - parseFloat(this.parentNode.currentStyle.paddingLeft) - parseFloat(this.parentNode.currentStyle.paddingRight))) + "px");
565 | /* */
566 | }
567 |
568 | .mobile-pull-75 {
569 | left: -75%;
570 | /* */
571 | *left: expression(Math.floor(-0.75 * (this.parentNode.offsetWidth - parseFloat(this.parentNode.currentStyle.paddingLeft) - parseFloat(this.parentNode.currentStyle.paddingRight))) + "px");
572 | /* */
573 | }
574 |
575 | .mobile-grid-80 {
576 | float: left;
577 | width: 80%;
578 | /* */
579 | *width: expression(Math.floor(0.8 * (this.parentNode.offsetWidth - parseFloat(this.parentNode.currentStyle.paddingLeft) - parseFloat(this.parentNode.currentStyle.paddingRight))) + "px");
580 | /* */
581 | }
582 |
583 | .mobile-prefix-80 {
584 | margin-left: 80%;
585 | }
586 |
587 | .mobile-suffix-80 {
588 | margin-right: 80%;
589 | }
590 |
591 | .mobile-push-80 {
592 | left: 80%;
593 | /* */
594 | *left: expression(Math.floor(0.8 * (this.parentNode.offsetWidth - parseFloat(this.parentNode.currentStyle.paddingLeft) - parseFloat(this.parentNode.currentStyle.paddingRight))) + "px");
595 | /* */
596 | }
597 |
598 | .mobile-pull-80 {
599 | left: -80%;
600 | /* */
601 | *left: expression(Math.floor(-0.8 * (this.parentNode.offsetWidth - parseFloat(this.parentNode.currentStyle.paddingLeft) - parseFloat(this.parentNode.currentStyle.paddingRight))) + "px");
602 | /* */
603 | }
604 |
605 | .mobile-grid-85 {
606 | float: left;
607 | width: 85%;
608 | /* */
609 | *width: expression(Math.floor(0.85 * (this.parentNode.offsetWidth - parseFloat(this.parentNode.currentStyle.paddingLeft) - parseFloat(this.parentNode.currentStyle.paddingRight))) + "px");
610 | /* */
611 | }
612 |
613 | .mobile-prefix-85 {
614 | margin-left: 85%;
615 | }
616 |
617 | .mobile-suffix-85 {
618 | margin-right: 85%;
619 | }
620 |
621 | .mobile-push-85 {
622 | left: 85%;
623 | /* */
624 | *left: expression(Math.floor(0.85 * (this.parentNode.offsetWidth - parseFloat(this.parentNode.currentStyle.paddingLeft) - parseFloat(this.parentNode.currentStyle.paddingRight))) + "px");
625 | /* */
626 | }
627 |
628 | .mobile-pull-85 {
629 | left: -85%;
630 | /* */
631 | *left: expression(Math.floor(-0.85 * (this.parentNode.offsetWidth - parseFloat(this.parentNode.currentStyle.paddingLeft) - parseFloat(this.parentNode.currentStyle.paddingRight))) + "px");
632 | /* */
633 | }
634 |
635 | .mobile-grid-90 {
636 | float: left;
637 | width: 90%;
638 | /* */
639 | *width: expression(Math.floor(0.9 * (this.parentNode.offsetWidth - parseFloat(this.parentNode.currentStyle.paddingLeft) - parseFloat(this.parentNode.currentStyle.paddingRight))) + "px");
640 | /* */
641 | }
642 |
643 | .mobile-prefix-90 {
644 | margin-left: 90%;
645 | }
646 |
647 | .mobile-suffix-90 {
648 | margin-right: 90%;
649 | }
650 |
651 | .mobile-push-90 {
652 | left: 90%;
653 | /* */
654 | *left: expression(Math.floor(0.9 * (this.parentNode.offsetWidth - parseFloat(this.parentNode.currentStyle.paddingLeft) - parseFloat(this.parentNode.currentStyle.paddingRight))) + "px");
655 | /* */
656 | }
657 |
658 | .mobile-pull-90 {
659 | left: -90%;
660 | /* */
661 | *left: expression(Math.floor(-0.9 * (this.parentNode.offsetWidth - parseFloat(this.parentNode.currentStyle.paddingLeft) - parseFloat(this.parentNode.currentStyle.paddingRight))) + "px");
662 | /* */
663 | }
664 |
665 | .mobile-grid-95 {
666 | float: left;
667 | width: 95%;
668 | /* */
669 | *width: expression(Math.floor(0.95 * (this.parentNode.offsetWidth - parseFloat(this.parentNode.currentStyle.paddingLeft) - parseFloat(this.parentNode.currentStyle.paddingRight))) + "px");
670 | /* */
671 | }
672 |
673 | .mobile-prefix-95 {
674 | margin-left: 95%;
675 | }
676 |
677 | .mobile-suffix-95 {
678 | margin-right: 95%;
679 | }
680 |
681 | .mobile-push-95 {
682 | left: 95%;
683 | /* */
684 | *left: expression(Math.floor(0.95 * (this.parentNode.offsetWidth - parseFloat(this.parentNode.currentStyle.paddingLeft) - parseFloat(this.parentNode.currentStyle.paddingRight))) + "px");
685 | /* */
686 | }
687 |
688 | .mobile-pull-95 {
689 | left: -95%;
690 | /* */
691 | *left: expression(Math.floor(-0.95 * (this.parentNode.offsetWidth - parseFloat(this.parentNode.currentStyle.paddingLeft) - parseFloat(this.parentNode.currentStyle.paddingRight))) + "px");
692 | /* */
693 | }
694 |
695 | .mobile-grid-33 {
696 | float: left;
697 | width: 33.33333%;
698 | /* */
699 | *width: expression(Math.floor(0.33333 * (this.parentNode.offsetWidth - parseFloat(this.parentNode.currentStyle.paddingLeft) - parseFloat(this.parentNode.currentStyle.paddingRight))) + "px");
700 | /* */
701 | }
702 |
703 | .mobile-prefix-33 {
704 | margin-left: 33.33333%;
705 | }
706 |
707 | .mobile-suffix-33 {
708 | margin-right: 33.33333%;
709 | }
710 |
711 | .mobile-push-33 {
712 | left: 33.33333%;
713 | /* */
714 | *left: expression(Math.floor(0.33333 * (this.parentNode.offsetWidth - parseFloat(this.parentNode.currentStyle.paddingLeft) - parseFloat(this.parentNode.currentStyle.paddingRight))) + "px");
715 | /* */
716 | }
717 |
718 | .mobile-pull-33 {
719 | left: -33.33333%;
720 | /* */
721 | *left: expression(Math.floor(-0.33333 * (this.parentNode.offsetWidth - parseFloat(this.parentNode.currentStyle.paddingLeft) - parseFloat(this.parentNode.currentStyle.paddingRight))) + "px");
722 | /* */
723 | }
724 |
725 | .mobile-grid-66 {
726 | float: left;
727 | width: 66.66667%;
728 | /* */
729 | *width: expression(Math.floor(0.66667 * (this.parentNode.offsetWidth - parseFloat(this.parentNode.currentStyle.paddingLeft) - parseFloat(this.parentNode.currentStyle.paddingRight))) + "px");
730 | /* */
731 | }
732 |
733 | .mobile-prefix-66 {
734 | margin-left: 66.66667%;
735 | }
736 |
737 | .mobile-suffix-66 {
738 | margin-right: 66.66667%;
739 | }
740 |
741 | .mobile-push-66 {
742 | left: 66.66667%;
743 | /* */
744 | *left: expression(Math.floor(0.66667 * (this.parentNode.offsetWidth - parseFloat(this.parentNode.currentStyle.paddingLeft) - parseFloat(this.parentNode.currentStyle.paddingRight))) + "px");
745 | /* */
746 | }
747 |
748 | .mobile-pull-66 {
749 | left: -66.66667%;
750 | /* */
751 | *left: expression(Math.floor(-0.66667 * (this.parentNode.offsetWidth - parseFloat(this.parentNode.currentStyle.paddingLeft) - parseFloat(this.parentNode.currentStyle.paddingRight))) + "px");
752 | /* */
753 | }
754 |
755 | .mobile-grid-100 {
756 | clear: both;
757 | width: 100%;
758 | }
759 | }
760 | @media screen and (min-width: 768px) {
761 | .grid-100:before,
762 | .grid-100:after {
763 | content: ".";
764 | display: block;
765 | overflow: hidden;
766 | visibility: hidden;
767 | font-size: 0;
768 | line-height: 0;
769 | width: 0;
770 | height: 0;
771 | }
772 |
773 | .grid-100:after {
774 | clear: both;
775 | }
776 |
777 | .grid-100 {
778 | /* */
779 | *zoom: 1;
780 | /* */
781 | }
782 |
783 | .push-5,
784 | .pull-5, .push-10,
785 | .pull-10, .push-15,
786 | .pull-15, .push-20,
787 | .pull-20, .push-25,
788 | .pull-25, .push-30,
789 | .pull-30, .push-35,
790 | .pull-35, .push-40,
791 | .pull-40, .push-45,
792 | .pull-45, .push-50,
793 | .pull-50, .push-55,
794 | .pull-55, .push-60,
795 | .pull-60, .push-65,
796 | .pull-65, .push-70,
797 | .pull-70, .push-75,
798 | .pull-75, .push-80,
799 | .pull-80, .push-85,
800 | .pull-85, .push-90,
801 | .pull-90, .push-95,
802 | .pull-95, .push-33,
803 | .pull-33, .push-66,
804 | .pull-66 {
805 | position: relative;
806 | }
807 |
808 | .hide-on-desktop {
809 | display: none !important;
810 | }
811 |
812 | .grid-5 {
813 | float: left;
814 | width: 5%;
815 | /* */
816 | *width: expression(Math.floor(0.05 * (this.parentNode.offsetWidth - parseFloat(this.parentNode.currentStyle.paddingLeft) - parseFloat(this.parentNode.currentStyle.paddingRight))) + "px");
817 | /* */
818 | }
819 |
820 | .prefix-5 {
821 | margin-left: 5%;
822 | }
823 |
824 | .suffix-5 {
825 | margin-right: 5%;
826 | }
827 |
828 | .push-5 {
829 | left: 5%;
830 | /* */
831 | *left: expression(Math.floor(0.05 * (this.parentNode.offsetWidth - parseFloat(this.parentNode.currentStyle.paddingLeft) - parseFloat(this.parentNode.currentStyle.paddingRight))) + "px");
832 | /* */
833 | }
834 |
835 | .pull-5 {
836 | left: -5%;
837 | /* */
838 | *left: expression(Math.floor(-0.05 * (this.parentNode.offsetWidth - parseFloat(this.parentNode.currentStyle.paddingLeft) - parseFloat(this.parentNode.currentStyle.paddingRight))) + "px");
839 | /* */
840 | }
841 |
842 | .grid-10 {
843 | float: left;
844 | width: 10%;
845 | /* */
846 | *width: expression(Math.floor(0.1 * (this.parentNode.offsetWidth - parseFloat(this.parentNode.currentStyle.paddingLeft) - parseFloat(this.parentNode.currentStyle.paddingRight))) + "px");
847 | /* */
848 | }
849 |
850 | .prefix-10 {
851 | margin-left: 10%;
852 | }
853 |
854 | .suffix-10 {
855 | margin-right: 10%;
856 | }
857 |
858 | .push-10 {
859 | left: 10%;
860 | /* */
861 | *left: expression(Math.floor(0.1 * (this.parentNode.offsetWidth - parseFloat(this.parentNode.currentStyle.paddingLeft) - parseFloat(this.parentNode.currentStyle.paddingRight))) + "px");
862 | /* */
863 | }
864 |
865 | .pull-10 {
866 | left: -10%;
867 | /* */
868 | *left: expression(Math.floor(-0.1 * (this.parentNode.offsetWidth - parseFloat(this.parentNode.currentStyle.paddingLeft) - parseFloat(this.parentNode.currentStyle.paddingRight))) + "px");
869 | /* */
870 | }
871 |
872 | .grid-15 {
873 | float: left;
874 | width: 15%;
875 | /* */
876 | *width: expression(Math.floor(0.15 * (this.parentNode.offsetWidth - parseFloat(this.parentNode.currentStyle.paddingLeft) - parseFloat(this.parentNode.currentStyle.paddingRight))) + "px");
877 | /* */
878 | }
879 |
880 | .prefix-15 {
881 | margin-left: 15%;
882 | }
883 |
884 | .suffix-15 {
885 | margin-right: 15%;
886 | }
887 |
888 | .push-15 {
889 | left: 15%;
890 | /* */
891 | *left: expression(Math.floor(0.15 * (this.parentNode.offsetWidth - parseFloat(this.parentNode.currentStyle.paddingLeft) - parseFloat(this.parentNode.currentStyle.paddingRight))) + "px");
892 | /* */
893 | }
894 |
895 | .pull-15 {
896 | left: -15%;
897 | /* */
898 | *left: expression(Math.floor(-0.15 * (this.parentNode.offsetWidth - parseFloat(this.parentNode.currentStyle.paddingLeft) - parseFloat(this.parentNode.currentStyle.paddingRight))) + "px");
899 | /* */
900 | }
901 |
902 | .grid-20 {
903 | float: left;
904 | width: 20%;
905 | /* */
906 | *width: expression(Math.floor(0.2 * (this.parentNode.offsetWidth - parseFloat(this.parentNode.currentStyle.paddingLeft) - parseFloat(this.parentNode.currentStyle.paddingRight))) + "px");
907 | /* */
908 | }
909 |
910 | .prefix-20 {
911 | margin-left: 20%;
912 | }
913 |
914 | .suffix-20 {
915 | margin-right: 20%;
916 | }
917 |
918 | .push-20 {
919 | left: 20%;
920 | /* */
921 | *left: expression(Math.floor(0.2 * (this.parentNode.offsetWidth - parseFloat(this.parentNode.currentStyle.paddingLeft) - parseFloat(this.parentNode.currentStyle.paddingRight))) + "px");
922 | /* */
923 | }
924 |
925 | .pull-20 {
926 | left: -20%;
927 | /* */
928 | *left: expression(Math.floor(-0.2 * (this.parentNode.offsetWidth - parseFloat(this.parentNode.currentStyle.paddingLeft) - parseFloat(this.parentNode.currentStyle.paddingRight))) + "px");
929 | /* */
930 | }
931 |
932 | .grid-25 {
933 | float: left;
934 | width: 25%;
935 | /* */
936 | *width: expression(Math.floor(0.25 * (this.parentNode.offsetWidth - parseFloat(this.parentNode.currentStyle.paddingLeft) - parseFloat(this.parentNode.currentStyle.paddingRight))) + "px");
937 | /* */
938 | }
939 |
940 | .prefix-25 {
941 | margin-left: 25%;
942 | }
943 |
944 | .suffix-25 {
945 | margin-right: 25%;
946 | }
947 |
948 | .push-25 {
949 | left: 25%;
950 | /* */
951 | *left: expression(Math.floor(0.25 * (this.parentNode.offsetWidth - parseFloat(this.parentNode.currentStyle.paddingLeft) - parseFloat(this.parentNode.currentStyle.paddingRight))) + "px");
952 | /* */
953 | }
954 |
955 | .pull-25 {
956 | left: -25%;
957 | /* */
958 | *left: expression(Math.floor(-0.25 * (this.parentNode.offsetWidth - parseFloat(this.parentNode.currentStyle.paddingLeft) - parseFloat(this.parentNode.currentStyle.paddingRight))) + "px");
959 | /* */
960 | }
961 |
962 | .grid-30 {
963 | float: left;
964 | width: 30%;
965 | /* */
966 | *width: expression(Math.floor(0.3 * (this.parentNode.offsetWidth - parseFloat(this.parentNode.currentStyle.paddingLeft) - parseFloat(this.parentNode.currentStyle.paddingRight))) + "px");
967 | /* */
968 | }
969 |
970 | .prefix-30 {
971 | margin-left: 30%;
972 | }
973 |
974 | .suffix-30 {
975 | margin-right: 30%;
976 | }
977 |
978 | .push-30 {
979 | left: 30%;
980 | /* */
981 | *left: expression(Math.floor(0.3 * (this.parentNode.offsetWidth - parseFloat(this.parentNode.currentStyle.paddingLeft) - parseFloat(this.parentNode.currentStyle.paddingRight))) + "px");
982 | /* */
983 | }
984 |
985 | .pull-30 {
986 | left: -30%;
987 | /* */
988 | *left: expression(Math.floor(-0.3 * (this.parentNode.offsetWidth - parseFloat(this.parentNode.currentStyle.paddingLeft) - parseFloat(this.parentNode.currentStyle.paddingRight))) + "px");
989 | /* */
990 | }
991 |
992 | .grid-35 {
993 | float: left;
994 | width: 35%;
995 | /* */
996 | *width: expression(Math.floor(0.35 * (this.parentNode.offsetWidth - parseFloat(this.parentNode.currentStyle.paddingLeft) - parseFloat(this.parentNode.currentStyle.paddingRight))) + "px");
997 | /* */
998 | }
999 |
1000 | .prefix-35 {
1001 | margin-left: 35%;
1002 | }
1003 |
1004 | .suffix-35 {
1005 | margin-right: 35%;
1006 | }
1007 |
1008 | .push-35 {
1009 | left: 35%;
1010 | /* */
1011 | *left: expression(Math.floor(0.35 * (this.parentNode.offsetWidth - parseFloat(this.parentNode.currentStyle.paddingLeft) - parseFloat(this.parentNode.currentStyle.paddingRight))) + "px");
1012 | /* */
1013 | }
1014 |
1015 | .pull-35 {
1016 | left: -35%;
1017 | /* */
1018 | *left: expression(Math.floor(-0.35 * (this.parentNode.offsetWidth - parseFloat(this.parentNode.currentStyle.paddingLeft) - parseFloat(this.parentNode.currentStyle.paddingRight))) + "px");
1019 | /* */
1020 | }
1021 |
1022 | .grid-40 {
1023 | float: left;
1024 | width: 40%;
1025 | /* */
1026 | *width: expression(Math.floor(0.4 * (this.parentNode.offsetWidth - parseFloat(this.parentNode.currentStyle.paddingLeft) - parseFloat(this.parentNode.currentStyle.paddingRight))) + "px");
1027 | /* */
1028 | }
1029 |
1030 | .prefix-40 {
1031 | margin-left: 40%;
1032 | }
1033 |
1034 | .suffix-40 {
1035 | margin-right: 40%;
1036 | }
1037 |
1038 | .push-40 {
1039 | left: 40%;
1040 | /* */
1041 | *left: expression(Math.floor(0.4 * (this.parentNode.offsetWidth - parseFloat(this.parentNode.currentStyle.paddingLeft) - parseFloat(this.parentNode.currentStyle.paddingRight))) + "px");
1042 | /* */
1043 | }
1044 |
1045 | .pull-40 {
1046 | left: -40%;
1047 | /* */
1048 | *left: expression(Math.floor(-0.4 * (this.parentNode.offsetWidth - parseFloat(this.parentNode.currentStyle.paddingLeft) - parseFloat(this.parentNode.currentStyle.paddingRight))) + "px");
1049 | /* */
1050 | }
1051 |
1052 | .grid-45 {
1053 | float: left;
1054 | width: 45%;
1055 | /* */
1056 | *width: expression(Math.floor(0.45 * (this.parentNode.offsetWidth - parseFloat(this.parentNode.currentStyle.paddingLeft) - parseFloat(this.parentNode.currentStyle.paddingRight))) + "px");
1057 | /* */
1058 | }
1059 |
1060 | .prefix-45 {
1061 | margin-left: 45%;
1062 | }
1063 |
1064 | .suffix-45 {
1065 | margin-right: 45%;
1066 | }
1067 |
1068 | .push-45 {
1069 | left: 45%;
1070 | /* */
1071 | *left: expression(Math.floor(0.45 * (this.parentNode.offsetWidth - parseFloat(this.parentNode.currentStyle.paddingLeft) - parseFloat(this.parentNode.currentStyle.paddingRight))) + "px");
1072 | /* */
1073 | }
1074 |
1075 | .pull-45 {
1076 | left: -45%;
1077 | /* */
1078 | *left: expression(Math.floor(-0.45 * (this.parentNode.offsetWidth - parseFloat(this.parentNode.currentStyle.paddingLeft) - parseFloat(this.parentNode.currentStyle.paddingRight))) + "px");
1079 | /* */
1080 | }
1081 |
1082 | .grid-50 {
1083 | float: left;
1084 | width: 50%;
1085 | /* */
1086 | *width: expression(Math.floor(0.5 * (this.parentNode.offsetWidth - parseFloat(this.parentNode.currentStyle.paddingLeft) - parseFloat(this.parentNode.currentStyle.paddingRight))) + "px");
1087 | /* */
1088 | }
1089 |
1090 | .prefix-50 {
1091 | margin-left: 50%;
1092 | }
1093 |
1094 | .suffix-50 {
1095 | margin-right: 50%;
1096 | }
1097 |
1098 | .push-50 {
1099 | left: 50%;
1100 | /* */
1101 | *left: expression(Math.floor(0.5 * (this.parentNode.offsetWidth - parseFloat(this.parentNode.currentStyle.paddingLeft) - parseFloat(this.parentNode.currentStyle.paddingRight))) + "px");
1102 | /* */
1103 | }
1104 |
1105 | .pull-50 {
1106 | left: -50%;
1107 | /* */
1108 | *left: expression(Math.floor(-0.5 * (this.parentNode.offsetWidth - parseFloat(this.parentNode.currentStyle.paddingLeft) - parseFloat(this.parentNode.currentStyle.paddingRight))) + "px");
1109 | /* */
1110 | }
1111 |
1112 | .grid-55 {
1113 | float: left;
1114 | width: 55%;
1115 | /* */
1116 | *width: expression(Math.floor(0.55 * (this.parentNode.offsetWidth - parseFloat(this.parentNode.currentStyle.paddingLeft) - parseFloat(this.parentNode.currentStyle.paddingRight))) + "px");
1117 | /* */
1118 | }
1119 |
1120 | .prefix-55 {
1121 | margin-left: 55%;
1122 | }
1123 |
1124 | .suffix-55 {
1125 | margin-right: 55%;
1126 | }
1127 |
1128 | .push-55 {
1129 | left: 55%;
1130 | /* */
1131 | *left: expression(Math.floor(0.55 * (this.parentNode.offsetWidth - parseFloat(this.parentNode.currentStyle.paddingLeft) - parseFloat(this.parentNode.currentStyle.paddingRight))) + "px");
1132 | /* */
1133 | }
1134 |
1135 | .pull-55 {
1136 | left: -55%;
1137 | /* */
1138 | *left: expression(Math.floor(-0.55 * (this.parentNode.offsetWidth - parseFloat(this.parentNode.currentStyle.paddingLeft) - parseFloat(this.parentNode.currentStyle.paddingRight))) + "px");
1139 | /* */
1140 | }
1141 |
1142 | .grid-60 {
1143 | float: left;
1144 | width: 60%;
1145 | /* */
1146 | *width: expression(Math.floor(0.6 * (this.parentNode.offsetWidth - parseFloat(this.parentNode.currentStyle.paddingLeft) - parseFloat(this.parentNode.currentStyle.paddingRight))) + "px");
1147 | /* */
1148 | }
1149 |
1150 | .prefix-60 {
1151 | margin-left: 60%;
1152 | }
1153 |
1154 | .suffix-60 {
1155 | margin-right: 60%;
1156 | }
1157 |
1158 | .push-60 {
1159 | left: 60%;
1160 | /* */
1161 | *left: expression(Math.floor(0.6 * (this.parentNode.offsetWidth - parseFloat(this.parentNode.currentStyle.paddingLeft) - parseFloat(this.parentNode.currentStyle.paddingRight))) + "px");
1162 | /* */
1163 | }
1164 |
1165 | .pull-60 {
1166 | left: -60%;
1167 | /* */
1168 | *left: expression(Math.floor(-0.6 * (this.parentNode.offsetWidth - parseFloat(this.parentNode.currentStyle.paddingLeft) - parseFloat(this.parentNode.currentStyle.paddingRight))) + "px");
1169 | /* */
1170 | }
1171 |
1172 | .grid-65 {
1173 | float: left;
1174 | width: 65%;
1175 | /* */
1176 | *width: expression(Math.floor(0.65 * (this.parentNode.offsetWidth - parseFloat(this.parentNode.currentStyle.paddingLeft) - parseFloat(this.parentNode.currentStyle.paddingRight))) + "px");
1177 | /* */
1178 | }
1179 |
1180 | .prefix-65 {
1181 | margin-left: 65%;
1182 | }
1183 |
1184 | .suffix-65 {
1185 | margin-right: 65%;
1186 | }
1187 |
1188 | .push-65 {
1189 | left: 65%;
1190 | /* */
1191 | *left: expression(Math.floor(0.65 * (this.parentNode.offsetWidth - parseFloat(this.parentNode.currentStyle.paddingLeft) - parseFloat(this.parentNode.currentStyle.paddingRight))) + "px");
1192 | /* */
1193 | }
1194 |
1195 | .pull-65 {
1196 | left: -65%;
1197 | /* */
1198 | *left: expression(Math.floor(-0.65 * (this.parentNode.offsetWidth - parseFloat(this.parentNode.currentStyle.paddingLeft) - parseFloat(this.parentNode.currentStyle.paddingRight))) + "px");
1199 | /* */
1200 | }
1201 |
1202 | .grid-70 {
1203 | float: left;
1204 | width: 70%;
1205 | /* */
1206 | *width: expression(Math.floor(0.7 * (this.parentNode.offsetWidth - parseFloat(this.parentNode.currentStyle.paddingLeft) - parseFloat(this.parentNode.currentStyle.paddingRight))) + "px");
1207 | /* */
1208 | }
1209 |
1210 | .prefix-70 {
1211 | margin-left: 70%;
1212 | }
1213 |
1214 | .suffix-70 {
1215 | margin-right: 70%;
1216 | }
1217 |
1218 | .push-70 {
1219 | left: 70%;
1220 | /* */
1221 | *left: expression(Math.floor(0.7 * (this.parentNode.offsetWidth - parseFloat(this.parentNode.currentStyle.paddingLeft) - parseFloat(this.parentNode.currentStyle.paddingRight))) + "px");
1222 | /* */
1223 | }
1224 |
1225 | .pull-70 {
1226 | left: -70%;
1227 | /* */
1228 | *left: expression(Math.floor(-0.7 * (this.parentNode.offsetWidth - parseFloat(this.parentNode.currentStyle.paddingLeft) - parseFloat(this.parentNode.currentStyle.paddingRight))) + "px");
1229 | /* */
1230 | }
1231 |
1232 | .grid-75 {
1233 | float: left;
1234 | width: 75%;
1235 | /* */
1236 | *width: expression(Math.floor(0.75 * (this.parentNode.offsetWidth - parseFloat(this.parentNode.currentStyle.paddingLeft) - parseFloat(this.parentNode.currentStyle.paddingRight))) + "px");
1237 | /* */
1238 | }
1239 |
1240 | .prefix-75 {
1241 | margin-left: 75%;
1242 | }
1243 |
1244 | .suffix-75 {
1245 | margin-right: 75%;
1246 | }
1247 |
1248 | .push-75 {
1249 | left: 75%;
1250 | /* */
1251 | *left: expression(Math.floor(0.75 * (this.parentNode.offsetWidth - parseFloat(this.parentNode.currentStyle.paddingLeft) - parseFloat(this.parentNode.currentStyle.paddingRight))) + "px");
1252 | /* */
1253 | }
1254 |
1255 | .pull-75 {
1256 | left: -75%;
1257 | /* */
1258 | *left: expression(Math.floor(-0.75 * (this.parentNode.offsetWidth - parseFloat(this.parentNode.currentStyle.paddingLeft) - parseFloat(this.parentNode.currentStyle.paddingRight))) + "px");
1259 | /* */
1260 | }
1261 |
1262 | .grid-80 {
1263 | float: left;
1264 | width: 80%;
1265 | /* */
1266 | *width: expression(Math.floor(0.8 * (this.parentNode.offsetWidth - parseFloat(this.parentNode.currentStyle.paddingLeft) - parseFloat(this.parentNode.currentStyle.paddingRight))) + "px");
1267 | /* */
1268 | }
1269 |
1270 | .prefix-80 {
1271 | margin-left: 80%;
1272 | }
1273 |
1274 | .suffix-80 {
1275 | margin-right: 80%;
1276 | }
1277 |
1278 | .push-80 {
1279 | left: 80%;
1280 | /* */
1281 | *left: expression(Math.floor(0.8 * (this.parentNode.offsetWidth - parseFloat(this.parentNode.currentStyle.paddingLeft) - parseFloat(this.parentNode.currentStyle.paddingRight))) + "px");
1282 | /* */
1283 | }
1284 |
1285 | .pull-80 {
1286 | left: -80%;
1287 | /* */
1288 | *left: expression(Math.floor(-0.8 * (this.parentNode.offsetWidth - parseFloat(this.parentNode.currentStyle.paddingLeft) - parseFloat(this.parentNode.currentStyle.paddingRight))) + "px");
1289 | /* */
1290 | }
1291 |
1292 | .grid-85 {
1293 | float: left;
1294 | width: 85%;
1295 | /* */
1296 | *width: expression(Math.floor(0.85 * (this.parentNode.offsetWidth - parseFloat(this.parentNode.currentStyle.paddingLeft) - parseFloat(this.parentNode.currentStyle.paddingRight))) + "px");
1297 | /* */
1298 | }
1299 |
1300 | .prefix-85 {
1301 | margin-left: 85%;
1302 | }
1303 |
1304 | .suffix-85 {
1305 | margin-right: 85%;
1306 | }
1307 |
1308 | .push-85 {
1309 | left: 85%;
1310 | /* */
1311 | *left: expression(Math.floor(0.85 * (this.parentNode.offsetWidth - parseFloat(this.parentNode.currentStyle.paddingLeft) - parseFloat(this.parentNode.currentStyle.paddingRight))) + "px");
1312 | /* */
1313 | }
1314 |
1315 | .pull-85 {
1316 | left: -85%;
1317 | /* */
1318 | *left: expression(Math.floor(-0.85 * (this.parentNode.offsetWidth - parseFloat(this.parentNode.currentStyle.paddingLeft) - parseFloat(this.parentNode.currentStyle.paddingRight))) + "px");
1319 | /* */
1320 | }
1321 |
1322 | .grid-90 {
1323 | float: left;
1324 | width: 90%;
1325 | /* */
1326 | *width: expression(Math.floor(0.9 * (this.parentNode.offsetWidth - parseFloat(this.parentNode.currentStyle.paddingLeft) - parseFloat(this.parentNode.currentStyle.paddingRight))) + "px");
1327 | /* */
1328 | }
1329 |
1330 | .prefix-90 {
1331 | margin-left: 90%;
1332 | }
1333 |
1334 | .suffix-90 {
1335 | margin-right: 90%;
1336 | }
1337 |
1338 | .push-90 {
1339 | left: 90%;
1340 | /* */
1341 | *left: expression(Math.floor(0.9 * (this.parentNode.offsetWidth - parseFloat(this.parentNode.currentStyle.paddingLeft) - parseFloat(this.parentNode.currentStyle.paddingRight))) + "px");
1342 | /* */
1343 | }
1344 |
1345 | .pull-90 {
1346 | left: -90%;
1347 | /* */
1348 | *left: expression(Math.floor(-0.9 * (this.parentNode.offsetWidth - parseFloat(this.parentNode.currentStyle.paddingLeft) - parseFloat(this.parentNode.currentStyle.paddingRight))) + "px");
1349 | /* */
1350 | }
1351 |
1352 | .grid-95 {
1353 | float: left;
1354 | width: 95%;
1355 | /* */
1356 | *width: expression(Math.floor(0.95 * (this.parentNode.offsetWidth - parseFloat(this.parentNode.currentStyle.paddingLeft) - parseFloat(this.parentNode.currentStyle.paddingRight))) + "px");
1357 | /* */
1358 | }
1359 |
1360 | .prefix-95 {
1361 | margin-left: 95%;
1362 | }
1363 |
1364 | .suffix-95 {
1365 | margin-right: 95%;
1366 | }
1367 |
1368 | .push-95 {
1369 | left: 95%;
1370 | /* */
1371 | *left: expression(Math.floor(0.95 * (this.parentNode.offsetWidth - parseFloat(this.parentNode.currentStyle.paddingLeft) - parseFloat(this.parentNode.currentStyle.paddingRight))) + "px");
1372 | /* */
1373 | }
1374 |
1375 | .pull-95 {
1376 | left: -95%;
1377 | /* */
1378 | *left: expression(Math.floor(-0.95 * (this.parentNode.offsetWidth - parseFloat(this.parentNode.currentStyle.paddingLeft) - parseFloat(this.parentNode.currentStyle.paddingRight))) + "px");
1379 | /* */
1380 | }
1381 |
1382 | .grid-33 {
1383 | float: left;
1384 | width: 33.33333%;
1385 | /* */
1386 | *width: expression(Math.floor(0.33333 * (this.parentNode.offsetWidth - parseFloat(this.parentNode.currentStyle.paddingLeft) - parseFloat(this.parentNode.currentStyle.paddingRight))) + "px");
1387 | /* */
1388 | }
1389 |
1390 | .prefix-33 {
1391 | margin-left: 33.33333%;
1392 | }
1393 |
1394 | .suffix-33 {
1395 | margin-right: 33.33333%;
1396 | }
1397 |
1398 | .push-33 {
1399 | left: 33.33333%;
1400 | /* */
1401 | *left: expression(Math.floor(0.33333 * (this.parentNode.offsetWidth - parseFloat(this.parentNode.currentStyle.paddingLeft) - parseFloat(this.parentNode.currentStyle.paddingRight))) + "px");
1402 | /* */
1403 | }
1404 |
1405 | .pull-33 {
1406 | left: -33.33333%;
1407 | /* */
1408 | *left: expression(Math.floor(-0.33333 * (this.parentNode.offsetWidth - parseFloat(this.parentNode.currentStyle.paddingLeft) - parseFloat(this.parentNode.currentStyle.paddingRight))) + "px");
1409 | /* */
1410 | }
1411 |
1412 | .grid-66 {
1413 | float: left;
1414 | width: 66.66667%;
1415 | /* */
1416 | *width: expression(Math.floor(0.66667 * (this.parentNode.offsetWidth - parseFloat(this.parentNode.currentStyle.paddingLeft) - parseFloat(this.parentNode.currentStyle.paddingRight))) + "px");
1417 | /* */
1418 | }
1419 |
1420 | .prefix-66 {
1421 | margin-left: 66.66667%;
1422 | }
1423 |
1424 | .suffix-66 {
1425 | margin-right: 66.66667%;
1426 | }
1427 |
1428 | .push-66 {
1429 | left: 66.66667%;
1430 | /* */
1431 | *left: expression(Math.floor(0.66667 * (this.parentNode.offsetWidth - parseFloat(this.parentNode.currentStyle.paddingLeft) - parseFloat(this.parentNode.currentStyle.paddingRight))) + "px");
1432 | /* */
1433 | }
1434 |
1435 | .pull-66 {
1436 | left: -66.66667%;
1437 | /* */
1438 | *left: expression(Math.floor(-0.66667 * (this.parentNode.offsetWidth - parseFloat(this.parentNode.currentStyle.paddingLeft) - parseFloat(this.parentNode.currentStyle.paddingRight))) + "px");
1439 | /* */
1440 | }
1441 |
1442 | .grid-100 {
1443 | clear: both;
1444 | width: 100%;
1445 | }
1446 | }
1447 |
--------------------------------------------------------------------------------
/app/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Angular and Browserify
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
--------------------------------------------------------------------------------
/app/js/app.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | require('es5-shim');
4 | require('es5-sham');
5 |
6 | require('jquery');
7 | var angular = require('angular');
8 | require('angular-route');
9 |
10 | var app = angular.module('todoApp', [ 'ngRoute' ]);
11 |
12 | app.constant('VERSION', require('../../package.json').version);
13 |
14 | require('./service');
15 | require('./controller');
16 |
17 | app.config(function($routeProvider) {
18 |
19 | $routeProvider.when('/todos', {
20 | templateUrl: 'views/todos.html',
21 | controller: 'TodoCtrl',
22 | })
23 | .when('/imprint', {
24 | templateUrl: 'views/imprint.html',
25 | controller: 'ImprintCtrl',
26 | })
27 | .otherwise({
28 | redirectTo: '/todos',
29 | });
30 | });
31 |
--------------------------------------------------------------------------------
/app/js/controller/edit_todo.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | module.exports = function($scope, TodoService) {
4 |
5 | var backupForCancel;
6 | var creatingNew = false;
7 |
8 | $scope.editMode = false;
9 |
10 | $scope.create = function() {
11 | $scope.$parent.todo = TodoService.create();
12 | backupForCancel = null;
13 | creatingNew = true;
14 | $scope.editMode = true;
15 | };
16 |
17 | $scope.edit = function() {
18 | if ($scope.editMode) {
19 | return;
20 | }
21 | backupForCancel = copy($scope.$parent.todo);
22 | creatingNew = false;
23 | $scope.editMode = true;
24 | };
25 |
26 | $scope.save = function() {
27 | if (creatingNew) {
28 | TodoService.insert($scope.$parent.todo);
29 | }
30 | $scope.editMode = false;
31 | creatingNew = false;
32 | backupForCancel = null;
33 | };
34 |
35 | $scope.cancel = function() {
36 | if (!creatingNew) {
37 | // rollback edits
38 | $scope.$parent.todo.title = backupForCancel.title;
39 | $scope.$parent.todo.due = backupForCancel.due;
40 | $scope.$parent.todo.text = backupForCancel.text;
41 | } else {
42 | // discard new todo, set active todo to some arbitrary todo
43 | $scope.$parent.todo = TodoService.getTodos()[0];
44 | creatingNew = false;
45 | }
46 | $scope.editMode = false;
47 | };
48 |
49 | $scope.remove = function() {
50 | TodoService.remove($scope.$parent.todo);
51 | // set active todo to some arbitrary todo
52 | $scope.$parent.todo = TodoService.getTodos()[0];
53 | };
54 |
55 | function copy(todo) {
56 | return {
57 | title: todo.title,
58 | due: todo.due,
59 | text: todo.text,
60 | };
61 | }
62 | };
63 |
--------------------------------------------------------------------------------
/app/js/controller/footer.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | module.exports = function($scope, VERSION) {
4 | $scope.version = VERSION;
5 | };
6 |
--------------------------------------------------------------------------------
/app/js/controller/imprint.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | module.exports = function($scope, ImprintService) {
4 | $scope.text = ImprintService.getText();
5 | };
6 |
--------------------------------------------------------------------------------
/app/js/controller/index.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | var app = require('angular').module('todoApp');
4 |
5 | app.controller('EditTodoCtrl', require('./edit_todo'));
6 | app.controller('FooterCtrl', require('./footer'));
7 | app.controller('TodoCtrl', require('./todo'));
8 | app.controller('TodoListCtrl', require('./todo_list'));
9 | app.controller('ImprintCtrl', require('./imprint'));
10 |
--------------------------------------------------------------------------------
/app/js/controller/todo.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | module.exports = function($scope, TodoService) {
4 | $scope.todo = TodoService.getTodos()[0];
5 | };
6 |
--------------------------------------------------------------------------------
/app/js/controller/todo_list.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | module.exports = function($scope, TodoService) {
4 |
5 | $scope.getTodos = TodoService.getTodos.bind(TodoService);
6 |
7 | $scope.select = function(todo) {
8 | $scope.$parent.todo = todo;
9 | };
10 |
11 | $scope.getCssClass = function(todo) {
12 | if (todo === $scope.$parent.todo) {
13 | return ['sidebar-item-active'];
14 | } else {
15 | return ['sidebar-item-inactive'];
16 | }
17 | };
18 |
19 | };
20 |
--------------------------------------------------------------------------------
/app/js/service/imprint.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | module.exports = function() {
4 |
5 | var text = 'Example app for using AngularJS with Browserify - ' +
6 | 'by Bastian Krol. Use at your own risk :P';
7 |
8 | this.getText = function() {
9 | return text;
10 | };
11 | };
12 |
--------------------------------------------------------------------------------
/app/js/service/index.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | var app = require('angular').module('todoApp');
4 |
5 | app.service('ImprintService', require('./imprint'));
6 | app.service('TodoService', require('./todos'));
7 |
--------------------------------------------------------------------------------
/app/js/service/todos.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | module.exports = function() {
4 |
5 | var todos = [{
6 | title: 'Buy milk',
7 | due: createDate(0, 0, 0, 18, 0),
8 | text: 'We are out of milk and coffee without milk is just unbearable.',
9 | }, {
10 | title: 'Write blog post',
11 | due: createDate(0, 0, 1, 14, 0),
12 | text: 'Write a blog post about how to integrate AngularJS and Browserify ' +
13 | 'for http://angularjs.de/',
14 | }, {
15 | title: 'Finish talk proposal',
16 | due: createDate(0, 0, 7, 23, 30),
17 | text: 'Finalize the talk proposal for FoobarConf. Call for papers ' +
18 | 'deadline is on Tuesday.',
19 | }, {
20 | title: 'World Domination',
21 | due: createDate(5, 0, 0, 12, 0),
22 | text: 'Because, who wouldn\'t want that?',
23 | }];
24 |
25 | this.getTodos = function() {
26 | return todos;
27 | };
28 |
29 | this.create = function() {
30 | return {
31 | title: '',
32 | due: createDate(0, 0, 1, 12, 0),
33 | text: '',
34 | };
35 | };
36 |
37 | this.insert = function(todo) {
38 | todos.push(todo);
39 | };
40 |
41 | this.remove = function(todo) {
42 | todos = todos.filter(function(t) { return t !== todo; });
43 | };
44 |
45 | function createDate(year, month, day, hour, minute) {
46 | var now = new Date();
47 | return new Date(
48 | now.getFullYear() + year,
49 | now.getMonth() + month,
50 | now.getDate() + day,
51 | hour, minute, 0, 0
52 | );
53 | }
54 |
55 | };
56 |
--------------------------------------------------------------------------------
/app/views/imprint.html:
--------------------------------------------------------------------------------
1 |
2 | {{ text }}
3 |
4 |
5 |
6 |
7 | Shut up and take me to the todo list!
8 |
--------------------------------------------------------------------------------
/app/views/todos.html:
--------------------------------------------------------------------------------
1 |
15 |
16 |
64 |
--------------------------------------------------------------------------------
/bin/browserify.sh:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 |
3 | # Script to browserify without Gulp - usually Gulp is used to browserify and
4 | # build everything.
5 |
6 | browserify_cmd=node_modules/browserify/bin/cmd.js
7 |
8 | bin_path=`dirname $0`
9 | pushd $bin_path/.. > /dev/null
10 | mkdir app/dist 2> /dev/null
11 |
12 | $browserify_cmd \
13 | --entry app/js/app.js \
14 | --outfile app/dist/app.js \
15 | --debug \
16 | --verbose
17 |
18 | $browserify_cmd \
19 | test/unit/controller/*.js \
20 | test/unit/service/*.js \
21 | --outfile test/browserified/browserified_tests.js \
22 | --debug \
23 | --verbose
24 |
25 | popd > /dev/null
26 |
--------------------------------------------------------------------------------
/bin/start-selenium.sh:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 |
3 | # Script to start selenium server for protractor tests.
4 |
5 | bin_path=`dirname $0`
6 | pushd $bin_path/.. > /dev/null
7 |
8 | node_modules/protractor/bin/webdriver-manager start
9 |
10 | # In case the selenium server does not stop after testing:
11 | # Type the following link into a browser:
12 | # http://localhost:4444/selenium-server/driver/?cmd=shutDownSeleniumServer
13 |
14 | popd > /dev/null
15 |
--------------------------------------------------------------------------------
/bin/watchify.sh:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 |
3 | # This script continuously browserifies the client side JavaScript, same as the
4 | # Gulp build would do. It gives faster turnaround times than a full Gulp
5 | # build. It does not execute JSHint or minification, just the browserify stuff.
6 | # Using this script only makes sense when index.html references the non-minified
7 | # build (that is, app/dist/app.js, not app/dist/app.min.js).
8 |
9 | # This script assumes that watchify is installed globally. To do that execute
10 | # npm install -g watchify
11 |
12 | # The watchify process is started in the background. Use
13 | # pkill -f watchify or pkill -f "node.*watchify"
14 | # to stop them.
15 |
16 | bin_path=`dirname $0`
17 | pushd $bin_path/.. > /dev/null
18 | mkdir app/dist 2> /dev/null
19 |
20 | watchify \
21 | --entry app/js/app.js \
22 | --outfile app/dist/app.js \
23 | --debug \
24 | --verbose \
25 | &
26 |
27 | watchify \
28 | test/unit/controller/*.js \
29 | test/unit/service/*.js \
30 | --outfile test/browserified/browserified_tests.js \
31 | --debug \
32 | --verbose \
33 | &
34 |
35 | popd > /dev/null
36 |
--------------------------------------------------------------------------------
/gulpfile.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | var browserify = require('browserify')
4 | , del = require('del')
5 | , source = require('vinyl-source-stream')
6 | , vinylPaths = require('vinyl-paths')
7 | , glob = require('glob')
8 | , Server = require('karma').Server
9 | , gulp = require('gulp');
10 |
11 | // Load all gulp plugins listed in package.json
12 | var gulpPlugins = require('gulp-load-plugins')({
13 | pattern: ['gulp-*', 'gulp.*'],
14 | replaceString: /\bgulp[\-.]/
15 | });
16 |
17 | // Define file path variables
18 | var paths = {
19 | root: 'app/', // App root path
20 | src: 'app/js/', // Source path
21 | dist: 'app/dist/', // Distribution path
22 | test: 'test/', // Test path
23 | };
24 |
25 | /*
26 | * Useful tasks:
27 | * - gulp fast:
28 | * - linting
29 | * - unit tests
30 | * - browserification
31 | * - no minification, does not start server.
32 | * - gulp watch:
33 | * - starts server with live reload enabled
34 | * - lints, unit tests, browserifies and live-reloads changes in browser
35 | * - no minification
36 | * - gulp:
37 | * - linting
38 | * - unit tests
39 | * - browserification
40 | * - minification and browserification of minified sources
41 | * - start server for e2e tests
42 | * - run Protractor End-to-end tests
43 | * - stop server immediately when e2e tests have finished
44 | *
45 | * At development time, you should usually just have 'gulp watch' running in the
46 | * background all the time. Use 'gulp' before releases.
47 | */
48 |
49 | var liveReload = true;
50 |
51 | gulp.task('clean', function () {
52 | return gulp
53 | .src([paths.root + 'ngAnnotate', paths.dist], {read: false})
54 | .pipe(vinylPaths(del));
55 | });
56 |
57 | gulp.task('lint', function () {
58 | return gulp
59 | .src(['gulpfile.js',
60 | paths.src + '**/*.js',
61 | paths.test + '**/*.js',
62 | '!' + paths.src + 'third-party/**',
63 | '!' + paths.test + 'browserified/**',
64 | ])
65 | .pipe(gulpPlugins.eslint())
66 | .pipe(gulpPlugins.eslint.format());
67 | });
68 |
69 | gulp.task('unit', function () {
70 | return gulp.src([
71 | paths.test + 'unit/**/*.js'
72 | ])
73 | .pipe(gulpPlugins.mocha({reporter: 'dot'}));
74 | });
75 |
76 | gulp.task('browserify', /*['lint', 'unit'],*/ function () {
77 | return browserify(paths.src + 'app.js', {debug: true})
78 | .bundle()
79 | .pipe(source('app.js'))
80 | .pipe(gulp.dest(paths.dist))
81 | .pipe(gulpPlugins.connect.reload());
82 | });
83 |
84 | gulp.task('ngAnnotate', ['lint', 'unit'], function () {
85 | return gulp.src([
86 | paths.src + '**/*.js',
87 | '!' + paths.src + 'third-party/**',
88 | ])
89 | .pipe(gulpPlugins.ngAnnotate())
90 | .pipe(gulp.dest(paths.root + 'ngAnnotate'));
91 | });
92 |
93 | gulp.task('browserify-min', ['ngAnnotate'], function () {
94 | return browserify(paths.root + 'ngAnnotate/app.js')
95 | .bundle()
96 | .pipe(source('app.min.js'))
97 | .pipe(gulpPlugins.streamify(gulpPlugins.uglify({mangle: false})))
98 | .pipe(gulp.dest(paths.dist));
99 | });
100 |
101 | gulp.task('browserify-tests', function () {
102 | var bundler = browserify({debug: true});
103 | glob
104 | .sync(paths.test + 'unit/**/*.js')
105 | .forEach(function (file) {
106 | bundler.add(file);
107 | });
108 | return bundler
109 | .bundle()
110 | .pipe(source('browserified_tests.js'))
111 | .pipe(gulp.dest(paths.test + 'browserified'));
112 | });
113 |
114 | gulp.task('karma', ['browserify-tests'], function (done) {
115 | new Server({
116 | configFile: __dirname + '/karma.conf.js',
117 | singleRun: true
118 | }, done).start();
119 | });
120 |
121 | gulp.task('server', ['browserify'], function () {
122 | gulpPlugins.connect.server({
123 | root: 'app',
124 | livereload: liveReload,
125 | });
126 | });
127 |
128 | gulp.task('e2e', ['server'], function () {
129 | return gulp.src([paths.test + 'e2e/**/*.js'])
130 | .pipe(gulpPlugins.protractor.protractor({
131 | configFile: 'protractor.conf.js',
132 | args: ['--baseUrl', 'http://127.0.0.1:8080'],
133 | }))
134 | .on('error', function (e) {
135 | throw e;
136 | })
137 | .on('end', function () {
138 | gulpPlugins.connect.serverClose();
139 | });
140 | });
141 |
142 | gulp.task('watch', function () {
143 | gulp.start('server');
144 | gulp.watch([
145 | paths.src + '**/*.js',
146 | '!' + paths.src + 'third-party/**',
147 | paths.test + '**/*.js',
148 | ], ['fast']);
149 | });
150 |
151 | gulp.task('fast', ['clean'], function () {
152 | gulp.start('browserify');
153 | });
154 |
155 | gulp.task('default', ['clean'], function () {
156 | liveReload = false;
157 | gulp.start('karma', 'browserify', 'browserify-min', 'e2e');
158 | });
159 |
--------------------------------------------------------------------------------
/karma.conf.js:
--------------------------------------------------------------------------------
1 | // Karma configuration
2 | // Generated on Mon May 26 2014 23:07:02 GMT+0200 (CEST)
3 |
4 | module.exports = function(config) {
5 | config.set({
6 |
7 | // base path that will be used to resolve all patterns (eg. files, exclude)
8 | basePath: '',
9 |
10 |
11 | // frameworks to use
12 | // available frameworks: https://npmjs.org/browse/keyword/karma-adapter
13 | frameworks: ['mocha'],
14 |
15 |
16 | // list of files / patterns to load in the browser
17 | files: [
18 | 'test/browserified/browserified_tests.js'
19 | ],
20 |
21 |
22 | // list of files to exclude
23 | exclude: [
24 | ],
25 |
26 |
27 | // preprocess matching files before serving them to the browser
28 | // available preprocessors: https://npmjs.org/browse/keyword/karma-preprocessor
29 | preprocessors: {
30 | },
31 |
32 |
33 | // test results reporter to use
34 | // possible values: 'dots', 'progress'
35 | // available reporters: https://npmjs.org/browse/keyword/karma-reporter
36 | reporters: ['progress'],
37 |
38 |
39 | // web server port
40 | port: 9876,
41 |
42 |
43 | // enable / disable colors in the output (reporters and logs)
44 | colors: true,
45 |
46 |
47 | // level of logging
48 | // possible values: config.LOG_DISABLE || config.LOG_ERROR || config.LOG_WARN || config.LOG_INFO || config.LOG_DEBUG
49 | logLevel: config.LOG_INFO,
50 |
51 |
52 | // enable / disable watching file and executing tests whenever any file changes
53 | autoWatch: true,
54 |
55 |
56 | // start these browsers
57 | // available browser launchers: https://npmjs.org/browse/keyword/karma-launcher
58 | browsers: ['Chrome', 'Firefox'],
59 |
60 |
61 | // Continuous Integration mode
62 | // if true, Karma captures browsers, runs the tests and exits
63 | singleRun: false
64 | });
65 | };
66 |
--------------------------------------------------------------------------------
/karma.conf.js.travis:
--------------------------------------------------------------------------------
1 | // Karma configuration
2 | // Generated on Mon May 26 2014 23:07:02 GMT+0200 (CEST)
3 |
4 | module.exports = function(config) {
5 | config.set({
6 |
7 | // base path that will be used to resolve all patterns (eg. files, exclude)
8 | basePath: '',
9 |
10 |
11 | // frameworks to use
12 | // available frameworks: https://npmjs.org/browse/keyword/karma-adapter
13 | frameworks: ['mocha'],
14 |
15 |
16 | // list of files / patterns to load in the browser
17 | files: [
18 | 'test/browserified/browserified_tests.js'
19 | ],
20 |
21 |
22 | // list of files to exclude
23 | exclude: [
24 | ],
25 |
26 |
27 | // preprocess matching files before serving them to the browser
28 | // available preprocessors: https://npmjs.org/browse/keyword/karma-preprocessor
29 | preprocessors: {
30 | },
31 |
32 |
33 | // test results reporter to use
34 | // possible values: 'dots', 'progress'
35 | // available reporters: https://npmjs.org/browse/keyword/karma-reporter
36 | reporters: ['progress'],
37 |
38 |
39 | // web server port
40 | port: 9876,
41 |
42 |
43 | // enable / disable colors in the output (reporters and logs)
44 | colors: true,
45 |
46 |
47 | // level of logging
48 | // possible values: config.LOG_DISABLE || config.LOG_ERROR || config.LOG_WARN || config.LOG_INFO || config.LOG_DEBUG
49 | logLevel: config.LOG_INFO,
50 |
51 |
52 | // enable / disable watching file and executing tests whenever any file changes
53 | autoWatch: false,
54 |
55 |
56 | // start these browsers
57 | // available browser launchers: https://npmjs.org/browse/keyword/karma-launcher
58 | browsers: ['Firefox'],
59 |
60 |
61 | // Continuous Integration mode
62 | // if true, Karma captures browsers, runs the tests and exits
63 | singleRun: true
64 | });
65 | };
66 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "angular-browserify-seed",
3 | "version": "0.1.0",
4 | "description": "Yet another example project with Angular, Browserify and Gulp",
5 | "repository": "https://github.com/basti1302/angular-browserify-seed",
6 | "license": "MIT",
7 | "scripts": {
8 | "postinstall": "webdriver-manager update",
9 | "pretest": "webdriver-manager start &",
10 | "test": "gulp"
11 | },
12 | "dependencies": {
13 | "angular": "^1.4.7",
14 | "angular-route": "^1.4.7",
15 | "es5-shim": "^4.3.1",
16 | "jquery": "^2.1.1"
17 | },
18 | "devDependencies": {
19 | "browserify": "^12.0.1",
20 | "browserify-shim": "^3.8.2",
21 | "chai": "^3.4.1",
22 | "del": "^2.1.0",
23 | "glob": "^6.0.1",
24 | "gulp": "^3.9.0",
25 | "gulp-connect": "^2.0.5",
26 | "gulp-eslint": "^1.1.0",
27 | "gulp-load-plugins": "^1.1.0",
28 | "gulp-mocha": "^2.2.0",
29 | "gulp-ng-annotate": "^1.1.0",
30 | "gulp-protractor": "1.0.0",
31 | "gulp-streamify": "1.0.2",
32 | "gulp-uglify": "^1.5.1",
33 | "karma": "^0.13.15",
34 | "karma-chai": "^0.1.0",
35 | "karma-chrome-launcher": "^0.2.1",
36 | "karma-firefox-launcher": "^0.1.3",
37 | "karma-mocha": "^0.2.1",
38 | "karma-sinon": "^1.0.3",
39 | "mocha": "^2.3.4",
40 | "protractor": "^2.5.1",
41 | "sinon": "^1.9.1",
42 | "sinon-chai": "^2.5.0",
43 | "vinyl-paths": "^2.1.0",
44 | "vinyl-source-stream": "^1.1.0"
45 | },
46 | "browser": {
47 | "es5-sham": "./node_modules/es5-shim/es5-sham.min.js",
48 | "es5-shim": "./node_modules/es5-shim/es5-shim.min.js"
49 | }
50 | }
51 |
--------------------------------------------------------------------------------
/protractor.conf.js:
--------------------------------------------------------------------------------
1 | exports.config = {
2 |
3 | chromeOnly: true,
4 | chromeDriver: './node_modules/protractor/selenium/chromedriver',
5 |
6 | capabilities: {
7 | 'browserName': 'chrome'
8 | },
9 |
10 | specs: ['test/e2e/**/*_spec.js'],
11 |
12 | rootElement: '.content',
13 |
14 | jasmineNodeOpts: {
15 | showColors: true,
16 | defaultTimeoutInterval: 30000
17 | }
18 | };
19 |
--------------------------------------------------------------------------------
/protractor.conf.js.travis:
--------------------------------------------------------------------------------
1 | exports.config = {
2 |
3 | seleniumAddress: 'http://0.0.0.0:4444/wd/hub',
4 |
5 | capabilities: {
6 | 'browserName': 'phantomjs'
7 | },
8 |
9 | specs: ['test/e2e/**/*_spec.js'],
10 |
11 | rootElement: '.content',
12 |
13 | jasmineNodeOpts: {
14 | showColors: true,
15 | defaultTimeoutInterval: 30000
16 | }
17 | };
18 |
--------------------------------------------------------------------------------
/readme.markdown:
--------------------------------------------------------------------------------
1 | UNMAINTAINED
2 | ============
3 |
4 | *DISCLAIMER: THIS REPOSITORY IS UNMAINTAINED!*
5 |
6 | It's up for grabs. If you are interested and want to take it over, open an issue to get into contact.
7 |
8 | AngularJS + Browserify Project Template
9 | =======================================
10 |
11 | [](https://travis-ci.org/angular-browserify/traverson)
12 |
13 | This is a small example/seed project for using AngularJS with Browserify. It demonstrates how to structure code by using CommonJS modules together with AngularJS' dependency injection mechanism.
14 |
15 | An accompanying blog post can be found at .
16 |
17 | Build
18 | -----
19 |
20 | This project comes with a `gulpfile` that includes:
21 |
22 | * running ESlint to lint JavaScript sources,
23 | * running unit tests via Mocha,
24 | * processing sources with Browserify (to create a non-minfied Browserify bundle),
25 | * ngAnnotate & uglify (to create an ngAnnotate-processed and minified Browserify bundle),
26 | * end-to-end tests with Protractor,
27 | * a static asset server (gulp-connect) and
28 | * live reload support.
29 |
30 | ### Useful gulp tasks
31 |
32 | The
33 | * `gulp fast`:
34 | * linting
35 | * unit tests
36 | * browserification
37 | * no minification, does not start server
38 | * `gulp watch`
39 | * starts server with live reload enabled
40 | * lints, unit tests, browserifies and live-reloads changes in browser
41 | * no minification
42 | * `gulp`:
43 | * linting
44 | * unit tests
45 | * browserification
46 | * minification and browserification of minified sources
47 | * start server for e2e tests
48 | * run Protractor End-to-end tests
49 | * stop server immediately when e2e tests have finished
50 |
51 | At development time, you should usually just have `gulp watch` running in the background all the time. Access the app via http://localhost:8080/. Whenever you change a source file and save it, the browserify bundle is recreated and your browser automatically reloads the changes. Use `gulp` (without a specific task) before releases.
52 |
--------------------------------------------------------------------------------
/test/browserified/.gitignore:
--------------------------------------------------------------------------------
1 | browserified_tests.js
2 |
--------------------------------------------------------------------------------
/test/browserified/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Browserify Tests Demo
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
20 |
21 |
22 |
23 |
24 |
25 |
32 |
33 |
34 |
--------------------------------------------------------------------------------
/test/e2e/delete_todo_spec.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | var TodoPage = require('./pages/todo_page');
4 |
5 | describe('The todo app (deleting a todo)', function() {
6 |
7 | var todoPage;
8 |
9 | beforeEach(function() {
10 | todoPage = new TodoPage();
11 | todoPage.open();
12 | // see comment in test/e2e/list_todo_spec.js
13 | browser.ignoreSynchronization = true;
14 | });
15 |
16 | it('should delete a todo', function() {
17 | todoPage.sidebarItem(2).click();
18 | todoPage.del();
19 | expect(todoPage.sidebarItems().count()).toEqual(3);
20 | });
21 |
22 | });
23 |
--------------------------------------------------------------------------------
/test/e2e/edit_todo_spec.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | var TodoPage = require('./pages/todo_page');
4 |
5 | describe('The todo app (editing)', function() {
6 |
7 | var todoPage;
8 |
9 | beforeEach(function() {
10 | todoPage = new TodoPage();
11 | todoPage.open();
12 | // see comment in test/e2e/list_todo_spec.js
13 | browser.ignoreSynchronization = true;
14 | });
15 |
16 | it('should be intially not in edit-mode', function() {
17 | todoPage.isInDisplayMode();
18 | });
19 |
20 | it('should switch to edit-mode', function() {
21 | todoPage.edit();
22 | todoPage.isInEditMode();
23 | });
24 |
25 | it('should edit and cancel', function() {
26 | todoPage.sidebarItem(1).click();
27 | todoPage.edit();
28 | todoPage.setTitle('changed title');
29 | todoPage.setText('changed text');
30 | todoPage.cancel();
31 | todoPage.isInDisplayMode();
32 | expect(todoPage.title.getText()).toEqual('Write blog post');
33 | expect(todoPage.text.getText()).toEqual('Write a blog post about how to ' +
34 | 'integrate AngularJS and Browserify for http://angularjs.de/');
35 | expect(todoPage.sidebarItem(1).getText()).toEqual('Write blog post');
36 | });
37 |
38 | it('should edit and save', function() {
39 | todoPage.sidebarItem(1).click();
40 | todoPage.edit();
41 | todoPage.setTitle('changed title');
42 | todoPage.setText('changed text');
43 | todoPage.save();
44 | todoPage.isInDisplayMode();
45 | expect(todoPage.title.getText()).toEqual('changed title');
46 | expect(todoPage.text.getText()).toEqual('changed text');
47 | expect(todoPage.sidebarItem(1).getText()).toEqual('changed title');
48 | });
49 |
50 | });
51 |
--------------------------------------------------------------------------------
/test/e2e/list_todo_spec.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | var TodoPage = require('./pages/todo_page');
4 |
5 | describe('The todo app', function() {
6 |
7 | var todoPage;
8 |
9 | beforeEach(function() {
10 | todoPage = new TodoPage();
11 | todoPage.open();
12 |
13 | // Um, this is not good. Not sure why it is needed :-(
14 | // Without it, we get an "Error while waiting for Protractor to sync with
15 | // the page: {}". There are several issues on GitHub describing that but
16 | // no solution, only workarounds like setting ignoreSynchronization = true
17 | // or waiting a bit at the start of the test.
18 | browser.ignoreSynchronization = true;
19 | });
20 |
21 | it('should list several todos items', function() {
22 | expect(todoPage.sidebarItem(0).getText()).toEqual('Buy milk');
23 | expect(todoPage.sidebarItem(1).getText()).toEqual('Write blog post');
24 | expect(todoPage.sidebarItem(2).getText()).toEqual(
25 | 'Finish talk proposal');
26 | expect(todoPage.sidebarItem(3).getText()).toEqual('World Domination');
27 | });
28 |
29 | it('should show details for the first todo item', function() {
30 | expect(todoPage.title.getText()).toEqual('Buy milk');
31 | expect(todoPage.text.getText()).toEqual('We are out of milk and coffee ' +
32 | 'without milk is just unbearable.');
33 | });
34 | });
35 |
--------------------------------------------------------------------------------
/test/e2e/new_todo_spec.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | var TodoPage = require('./pages/todo_page');
4 |
5 | describe('The todo app (creating a new todo)', function() {
6 |
7 | var todoPage;
8 |
9 | beforeEach(function() {
10 | todoPage = new TodoPage();
11 | todoPage.open();
12 | // see comment in test/e2e/list_todo_spec.js
13 | browser.ignoreSynchronization = true;
14 | });
15 |
16 | it('should switch to edit-mode when creating a new todo', function() {
17 | todoPage.createNew();
18 | todoPage.isInEditMode();
19 | });
20 |
21 | it('should start with an empty todo', function() {
22 | todoPage.createNew();
23 | expect(todoPage.titleInput.getText()).toEqual('');
24 | expect(todoPage.textInput.getText()).toEqual('');
25 | });
26 |
27 | it('should create a new todo and cancel', function() {
28 | todoPage.createNew();
29 | todoPage.setTitle('new title');
30 | todoPage.setText('new text');
31 | todoPage.cancel();
32 | todoPage.isInDisplayMode();
33 | expect(todoPage.sidebarItems().count()).toEqual(4);
34 | todoPage.doesNotContainText('new title');
35 | todoPage.doesNotContainText('new text');
36 | });
37 |
38 | it('should create a new todo and save', function() {
39 | todoPage.createNew();
40 | todoPage.setTitle('new title');
41 | todoPage.setText('new text');
42 | todoPage.save();
43 | todoPage.isInDisplayMode();
44 | expect(todoPage.sidebarItems().count()).toEqual(5);
45 | expect(todoPage.sidebarItem(4).getText()).toEqual('new title');
46 | expect(todoPage.title.getText()).toEqual('new title');
47 | expect(todoPage.text.getText()).toEqual('new text');
48 | });
49 |
50 | });
51 |
--------------------------------------------------------------------------------
/test/e2e/pages/todo_page.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | /*
4 | * Page object for the todo page.
5 | */
6 | var TodoPage = function() {
7 |
8 | var driver = browser.driver;
9 |
10 | this.title = element(by.css('.current-item'));
11 | this.dueDate = element(by.binding('todo.due'));
12 | this.text = element(by.binding('todo.text'));
13 |
14 | this.titleInput = element(by.model('todo.title'));
15 | this.textInput = element(by.model('todo.text'));
16 |
17 | var sidebarItemsLocator = by.repeater('todo in getTodos()');
18 |
19 | this.editButton = element(by.buttonText('Edit'));
20 | this.newButton = element(by.buttonText('New'));
21 | this.deleteButton = element(by.buttonText('Delete'));
22 | this.cancelButton = element(by.buttonText('Cancel'));
23 | this.saveButton = element(by.buttonText('Save'));
24 |
25 | this.open = function() {
26 | browser.get('http://127.0.0.1:8080/#/todos');
27 | };
28 |
29 | this.sidebarItems = function() {
30 | return element.all(sidebarItemsLocator);
31 | };
32 |
33 | this.sidebarItem = function(index) {
34 | return element(sidebarItemsLocator.row(index).column('title'));
35 | };
36 |
37 | this.setTitle = function(title) {
38 | enter(this.titleInput, title);
39 | };
40 |
41 | this.setText = function(text) {
42 | enter(this.textInput, text);
43 | };
44 |
45 | this.edit = function() {
46 | this.editButton.click();
47 | };
48 |
49 | this.createNew = function() {
50 | this.newButton.click();
51 | };
52 |
53 | this.del = function() {
54 | this.deleteButton.click();
55 | };
56 |
57 | this.cancel = function() {
58 | this.cancelButton.click();
59 | };
60 |
61 | this.save = function() {
62 | this.saveButton.click();
63 | };
64 |
65 | this.isInDisplayMode = function() {
66 | expect(this.title.isDisplayed()).toEqual(true);
67 | expect(this.titleInput.isDisplayed()).toEqual(false);
68 | expect(this.text.isDisplayed()).toEqual(true);
69 | expect(this.textInput.isDisplayed()).toEqual(false);
70 | expect(this.editButton.isDisplayed()).toEqual(true);
71 | expect(this.newButton.isDisplayed()).toEqual(true);
72 | expect(this.deleteButton.isDisplayed()).toEqual(true);
73 | expect(this.cancelButton.isDisplayed()).toEqual(false);
74 | expect(this.saveButton.isDisplayed()).toEqual(false);
75 | };
76 |
77 | this.isInEditMode = function() {
78 | expect(this.title.isDisplayed()).toEqual(false);
79 | expect(this.titleInput.isDisplayed()).toEqual(true);
80 | expect(this.text.isDisplayed()).toEqual(false);
81 | expect(this.textInput.isDisplayed()).toEqual(true);
82 | expect(this.editButton.isDisplayed()).toEqual(false);
83 | expect(this.newButton.isDisplayed()).toEqual(false);
84 | expect(this.deleteButton.isDisplayed()).toEqual(false);
85 | expect(this.cancelButton.isDisplayed()).toEqual(true);
86 | expect(this.saveButton.isDisplayed()).toEqual(true);
87 | };
88 |
89 | this.containsText = function(text) {
90 | checkText(text, function(result) {
91 | expect(result).toBe(true);
92 | });
93 | };
94 |
95 | this.doesNotContainText = function(text) {
96 | checkText(text, function(result) {
97 | expect(result).toBe(false);
98 | });
99 | };
100 |
101 | function checkText(text, fn) {
102 | driver
103 | .isElementPresent({
104 | xpath: '//*[contains(text(), \'' + text + '\')]'
105 | }).then(fn);
106 | }
107 | };
108 |
109 | function enter(field, text) {
110 | field.clear();
111 | field.sendKeys(text);
112 | }
113 |
114 | module.exports = TodoPage;
115 |
--------------------------------------------------------------------------------
/test/e2e/select_todo_spec.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | var TodoPage = require('./pages/todo_page');
4 |
5 | describe('The todo app', function() {
6 |
7 | var todoPage;
8 |
9 | beforeEach(function() {
10 | todoPage = new TodoPage();
11 | todoPage.open();
12 | // see comment in test/e2e/list_todo_spec.js
13 | browser.ignoreSynchronization = true;
14 | });
15 |
16 | it('should select a different todo from the sidebar', function() {
17 | todoPage.sidebarItem(1).click();
18 | expect(todoPage.title.getText()).toEqual('Write blog post');
19 | expect(todoPage.text.getText()).toEqual('Write a blog post about how to ' +
20 | 'integrate AngularJS and Browserify for http://angularjs.de/');
21 | });
22 | });
23 |
--------------------------------------------------------------------------------
/test/mocha.opts:
--------------------------------------------------------------------------------
1 | --recursive
2 | --reporter spec
3 |
--------------------------------------------------------------------------------
/test/unit/controller/edit_todo.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | var chai = require('chai')
4 | , expect = chai.expect
5 | , sinon = require('sinon')
6 | , sinonChai = require('sinon-chai');
7 |
8 | chai.use(sinonChai);
9 |
10 | var EditTodoCtrlModule = require('../../../app/js/controller/edit_todo.js');
11 |
12 | describe('The EditTodoCtrl\'s', function() {
13 |
14 | var todo;
15 | var $scope;
16 | var TodoService;
17 |
18 | beforeEach(function() {
19 | todo = {
20 | title: 'Todo',
21 | due: '2015-02-13',
22 | text: 'Do it',
23 | };
24 |
25 | $scope = {
26 | $parent: {
27 | todo: todo
28 | }
29 | };
30 |
31 | TodoService = {
32 | getTodos: sinon.stub().returns([{}]),
33 | create: sinon.spy(),
34 | insert: sinon.spy(),
35 | remove: sinon.spy(),
36 | };
37 |
38 | EditTodoCtrlModule($scope, TodoService);
39 | });
40 |
41 | describe('create workflow', function() {
42 |
43 | it('should create an new todo', function() {
44 | $scope.create();
45 | expect(TodoService.create).to.have.been.calledOnce;
46 | expect($scope.editMode).to.be.true;
47 | });
48 |
49 | it('should save a new todo', function() {
50 | $scope.create();
51 | $scope.save();
52 | expect(TodoService.insert).to.have.been.calledOnce;
53 | expect($scope.editMode).to.be.false;
54 | });
55 |
56 | it('should cancel the creation of a new todo', function() {
57 | $scope.create();
58 | $scope.cancel();
59 | expect(TodoService.insert).to.not.have.been.called;
60 | expect($scope.editMode).to.be.false;
61 | });
62 | });
63 |
64 | describe('edit workflow', function() {
65 |
66 | it('should edit a todo', function() {
67 | $scope.edit();
68 | expect($scope.editMode).to.be.true;
69 | });
70 |
71 | it('should save an edited todo', function() {
72 | $scope.edit();
73 | $scope.save();
74 | expect(TodoService.insert).to.not.have.been.called;
75 | expect($scope.editMode).to.be.false;
76 | });
77 |
78 | it('should cancel the editing of an existing todo', function() {
79 | $scope.edit();
80 | $scope.$parent.todo.title = 'changed';
81 | $scope.cancel();
82 | expect(TodoService.insert).to.not.have.been.called;
83 | expect($scope.$parent.todo.title).to.equal('Todo');
84 | expect($scope.editMode).to.be.false;
85 | });
86 | });
87 |
88 | it('should remove a todo item', function() {
89 | var t = $scope.$parent.todo;
90 | $scope.remove();
91 | expect(TodoService.remove).to.have.been.calledWith(t);
92 | });
93 |
94 | });
95 |
--------------------------------------------------------------------------------
/test/unit/controller/todo_list.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | var chai = require('chai')
4 | , expect = chai.expect;
5 |
6 | var TodoListCtrlModule = require('../../../app/js/controller/todo_list.js');
7 |
8 | describe('The TodoListCtrl', function() {
9 |
10 | var todo;
11 | var $scope;
12 |
13 | beforeEach(function() {
14 | todo = {
15 | title: 'Todo',
16 | due: '2015-02-13',
17 | text: 'Do it',
18 | };
19 |
20 | $scope = {
21 | $parent: {
22 | todo: todo
23 | }
24 | };
25 |
26 | var TodoService = {
27 | getTodos: function() {},
28 | };
29 |
30 | TodoListCtrlModule($scope, TodoService);
31 | });
32 |
33 | it('should highlight the active todo item', function() {
34 | var styles = $scope.getCssClass(todo);
35 | expect(styles).to.be.instanceof(Array);
36 | expect(styles.length).to.equal(1);
37 | expect(styles[0]).to.equal('sidebar-item-active');
38 | });
39 |
40 | it('should not highlight an inactive todo item', function() {
41 | var styles = $scope.getCssClass({});
42 | expect(styles).to.be.instanceof(Array);
43 | expect(styles.length).to.equal(1);
44 | expect(styles[0]).to.equal('sidebar-item-inactive');
45 | });
46 |
47 | });
48 |
--------------------------------------------------------------------------------
/test/unit/service/imprint.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | var chai = require('chai')
4 | , expect = chai.expect;
5 |
6 | var ImprintServiceModule = require('../../../app/js/service/imprint.js');
7 |
8 | describe('The ImprintService', function() {
9 |
10 | var ImprintService;
11 |
12 | beforeEach(function() {
13 | ImprintService = new ImprintServiceModule();
14 | });
15 |
16 | it('should provide the imprint text', function() {
17 | var text = ImprintService.getText();
18 | expect(text.length).to.be.above(30);
19 | });
20 |
21 | });
22 |
--------------------------------------------------------------------------------
/test/unit/service/todos.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | var chai = require('chai')
4 | , expect = chai.expect;
5 |
6 | var TodoServiceModule = require('../../../app/js/service/todos.js');
7 |
8 | describe('The TodoService', function() {
9 |
10 | var TodoService;
11 |
12 | beforeEach(function() {
13 | TodoService = new TodoServiceModule();
14 | });
15 |
16 | it('should have some todos initially', function() {
17 | var todos = TodoService.getTodos();
18 | expect(todos.length).to.equal(4);
19 | expect(todos[0].title).to.equal('Buy milk');
20 | });
21 |
22 | it('should create a todo', function() {
23 | var todo = TodoService.create();
24 | expect(todo.title).to.exist;
25 | expect(todo.title).to.be.equal('');
26 | expect(todo.due).to.exist;
27 | expect(todo.text).to.exist;
28 | expect(todo.text).to.exist;
29 | });
30 |
31 | it('should insert a todo', function() {
32 | TodoService.insert({ title: 'test' });
33 | var todos = TodoService.getTodos();
34 | expect(todos.length).to.equal(5);
35 | expect(todos[4].title).to.equal('test');
36 | });
37 |
38 | it('should remove a todo, based on object identity', function() {
39 | TodoService.remove(TodoService.getTodos()[2]);
40 | var todos = TodoService.getTodos();
41 | expect(todos.length).to.equal(3);
42 | expect(todos[1].title).to.equal('Write blog post');
43 | expect(todos[2].title).to.equal('World Domination');
44 | });
45 |
46 | });
47 |
--------------------------------------------------------------------------------