├── .gitignore
├── package.json
├── demos
├── autoprefixed
│ ├── signup.scss
│ ├── css
│ │ └── signup.css
│ └── index.html
├── flexie
│ ├── signup.scss
│ ├── css
│ │ └── signup.css
│ ├── index.html
│ └── flexie.js
├── latest_syntax_only
│ ├── css
│ │ └── signup.css
│ ├── signup.scss
│ └── index.html
└── progressive_enhancement
│ ├── signup.scss
│ ├── css
│ └── signup.css
│ └── index.html
├── signup.scss
├── Gruntfile.js
├── index.html
└── flexie.js
/.gitignore:
--------------------------------------------------------------------------------
1 | /signup.css
2 | /css/signup.css
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "engines": {
3 | "node": ">= 0.10.0"
4 | },
5 | "devDependencies": {
6 | "grunt": "~0.4.2",
7 | "grunt-contrib-jshint": "~0.7.2",
8 | "grunt-contrib-watch": "~0.5.3",
9 | "grunt-contrib-qunit": "~0.3.0",
10 | "grunt-contrib-concat": "~0.3.0",
11 | "grunt-contrib-uglify": "~0.2.7",
12 | "grunt-autoprefixer": "~0.7.2",
13 | "grunt-sass": "~0.11.0"
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/demos/autoprefixed/signup.scss:
--------------------------------------------------------------------------------
1 |
2 | /* Layout */
3 | body {
4 | padding: 20px 0;
5 | }
6 |
7 | .outer {
8 | max-width: 730px;
9 | margin: 0 auto;
10 | }
11 |
12 | .jumbotron {
13 | text-align: center;
14 | font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif;
15 | }
16 |
17 | .plans {
18 | display: flex;
19 |
20 | > div {
21 | flex: 1 1 33%;
22 | display: flex;
23 | flex-direction: column;
24 | align-items: flex-start;
25 |
26 | .stretch {
27 | width: 100%;
28 | flex: 1 0 auto;
29 | }
30 |
31 | a {
32 | margin-top: 16px;
33 | margin-top: 1rem;
34 | }
35 | }
36 |
37 | }
38 |
39 | .marketing {
40 | margin-bottom: 6 * 16px;
41 | margin-bottom: 6rem;
42 | }
43 |
44 | .well form .inputs{
45 | display: flex;
46 |
47 | #email {
48 | flex: 1 0 auto;
49 | }
50 | .btn {
51 | width: 25 * 10px;
52 | width: 25rem;
53 | margin-left: 16px;
54 | margin-left: 1rem;
55 | }
56 | }
57 |
58 | .footer {
59 | border-top: 1px solid #eee;
60 | padding-top: 2 * 16px;
61 | padding-top: 2rem;
62 | display: flex;
63 | p {
64 | flex: 1 0 auto;
65 | }
66 | a {
67 | padding-left: 16px;
68 | padding-left: 1rem;
69 | }
70 | }
--------------------------------------------------------------------------------
/signup.scss:
--------------------------------------------------------------------------------
1 |
2 | /* Layout */
3 | body {
4 | padding: 20px 0;
5 | }
6 |
7 | .outer {
8 | max-width: 730px;
9 | margin: 0 auto;
10 | }
11 |
12 | .jumbotron {
13 | text-align: center;
14 | font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif;
15 | }
16 |
17 | .plans {
18 | display: flex;
19 |
20 | > div {
21 | width: 33%;
22 | flex: 1 1 0;
23 | display: flex;
24 | flex-direction: column;
25 | align-items: flex-start;
26 |
27 | .stretch {
28 | width: 100%;
29 | flex: 1 0 auto;
30 | }
31 |
32 | a {
33 | margin-top: 16px;
34 | margin-top: 1rem;
35 | }
36 | }
37 |
38 | }
39 |
40 | .marketing {
41 | margin-bottom: 6 * 16px;
42 | margin-bottom: 6rem;
43 | }
44 |
45 | .well form .inputs{
46 | display: flex;
47 |
48 | #email {
49 | flex: 1 0 auto;
50 | }
51 | .btn {
52 | width: 25 * 10px;
53 | width: 25rem;
54 | margin-left: 16px;
55 | margin-left: 1rem;
56 | }
57 | }
58 |
59 | .footer {
60 | border-top: 1px solid #eee;
61 | padding-top: 2 * 16px;
62 | padding-top: 2rem;
63 | display: flex;
64 | p {
65 | flex: 1 0 auto;
66 | }
67 | a {
68 | padding-left: 16px;
69 | padding-left: 1rem;
70 | }
71 | }
--------------------------------------------------------------------------------
/demos/flexie/signup.scss:
--------------------------------------------------------------------------------
1 |
2 | /* Layout */
3 | body {
4 | padding: 20px 0;
5 | }
6 |
7 | .outer {
8 | max-width: 730px;
9 | margin: 0 auto;
10 | }
11 |
12 | .jumbotron {
13 | text-align: center;
14 | font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif;
15 | }
16 |
17 | .plans {
18 | display: flex;
19 |
20 | > div {
21 | width: 33%;
22 | flex: 1 1 0;
23 | display: flex;
24 | flex-direction: column;
25 | align-items: flex-start;
26 |
27 | .stretch {
28 | width: 100%;
29 | flex: 1 0 auto;
30 | }
31 |
32 | a {
33 | margin-top: 16px;
34 | margin-top: 1rem;
35 | }
36 | }
37 |
38 | }
39 |
40 | .marketing {
41 | margin-bottom: 6 * 16px;
42 | margin-bottom: 6rem;
43 | }
44 |
45 | .well form .inputs{
46 | display: flex;
47 |
48 | #email {
49 | flex: 1 0 auto;
50 | }
51 | .btn {
52 | width: 25 * 10px;
53 | width: 25rem;
54 | margin-left: 16px;
55 | margin-left: 1rem;
56 | }
57 | }
58 |
59 | .footer {
60 | border-top: 1px solid #eee;
61 | padding-top: 2 * 16px;
62 | padding-top: 2rem;
63 | display: flex;
64 | p {
65 | flex: 1 0 auto;
66 | }
67 | a {
68 | padding-left: 16px;
69 | padding-left: 1rem;
70 | }
71 | }
--------------------------------------------------------------------------------
/demos/latest_syntax_only/css/signup.css:
--------------------------------------------------------------------------------
1 | /* Layout */
2 | body {
3 | padding: 20px 0; }
4 |
5 | .outer {
6 | max-width: 730px;
7 | margin: 0 auto; }
8 |
9 | .jumbotron {
10 | text-align: center;
11 | font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; }
12 |
13 | .plans {
14 | display: -webkit-flex;
15 | display: flex; }
16 | .plans > div {
17 | width: 33%;
18 | -webkit-flex: 1 1 0;
19 | flex: 1 1 0;
20 | display: -webkit-flex;
21 | display: flex;
22 | -webkit-flex-direction: column;
23 | flex-direction: column;
24 | -webkit-align-items: flex-start;
25 | align-items: flex-start; }
26 | .plans > div .stretch {
27 | width: 100%;
28 | margin-bottom: 16px;
29 | margin-bottom: 1rem; }
30 | .plans > div a {
31 | margin-top: auto; }
32 |
33 | .marketing {
34 | margin-bottom: 96px;
35 | margin-bottom: 6rem; }
36 |
37 | .well form .inputs {
38 | display: -webkit-flex;
39 | display: flex; }
40 | .well form .inputs #email {
41 | -webkit-flex: 1 0 auto;
42 | flex: 1 0 auto; }
43 | .well form .inputs .btn {
44 | width: 250px;
45 | width: 25rem;
46 | margin-left: 16px;
47 | margin-left: 1rem; }
48 |
49 | .footer {
50 | border-top: 1px solid #eee;
51 | padding-top: 32px;
52 | padding-top: 2rem;
53 | display: -webkit-flex;
54 | display: flex; }
55 | .footer p {
56 | -webkit-flex: 1 0 auto;
57 | flex: 1 0 auto; }
58 | .footer a {
59 | padding-left: 16px;
60 | padding-left: 1rem; }
61 |
--------------------------------------------------------------------------------
/demos/progressive_enhancement/signup.scss:
--------------------------------------------------------------------------------
1 |
2 | /* Layout */
3 | body {
4 | padding: 20px 0;
5 | }
6 |
7 | .outer {
8 | max-width: 730px;
9 | margin: 0 auto;
10 | }
11 |
12 | .jumbotron {
13 | text-align: center;
14 | font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif;
15 | }
16 |
17 | .plans {
18 | display: flex;
19 |
20 | > div {
21 | width: 33%;
22 | float: left;
23 | flex: 1 1 0;
24 | display: flex;
25 | flex-direction: column;
26 | align-items: flex-start;
27 |
28 | .stretch {
29 | width: 100%;
30 | flex: 1 1 auto;
31 | }
32 |
33 | a {
34 | margin-top: 16px;
35 | margin-top: 1rem;
36 | }
37 | }
38 |
39 | }
40 |
41 | .marketing {
42 | margin-bottom: 6 * 16px;
43 | margin-bottom: 6rem;
44 | }
45 |
46 | .well form .inputs{
47 | display: flex;
48 |
49 | #email {
50 | width: 50%;
51 | display: inline;
52 | flex: 1 0 auto;
53 | }
54 | .btn {
55 | width: 25 * 10px;
56 | width: 25rem;
57 | margin-left: 16px;
58 | margin-left: 1rem;
59 | }
60 | }
61 |
62 | .footer {
63 | border-top: 1px solid #eee;
64 | padding-top: 2 * 16px;
65 | padding-top: 2rem;
66 | display: flex;
67 | p {
68 | float: left;
69 | flex: 1 0 auto;
70 | }
71 | > a {
72 | float: right;
73 | padding-left: 16px;
74 | padding-left: 1rem;
75 | }
76 | }
--------------------------------------------------------------------------------
/demos/latest_syntax_only/signup.scss:
--------------------------------------------------------------------------------
1 |
2 | /* Layout */
3 | body {
4 | padding: 20px 0;
5 | }
6 |
7 | .outer {
8 | max-width: 730px;
9 | margin: 0 auto;
10 | }
11 |
12 | .jumbotron {
13 | text-align: center;
14 | font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif;
15 | }
16 |
17 | .plans {
18 | display: -webkit-flex;
19 | display: flex;
20 |
21 | > div {
22 | width: 33%;
23 | -webkit-flex: 1 1 0;
24 | flex: 1 1 0;
25 | display: -webkit-flex;
26 | display: flex;
27 | -webkit-flex-direction: column;
28 | flex-direction: column;
29 | -webkit-align-items: flex-start;
30 | align-items: flex-start;
31 |
32 | .stretch {
33 | width: 100%;
34 | margin-bottom: 16px;
35 | margin-bottom: 1rem;
36 | }
37 |
38 | a {
39 | margin-top: auto;
40 | }
41 | }
42 |
43 | }
44 |
45 | .marketing {
46 | margin-bottom: 6 * 16px;
47 | margin-bottom: 6rem;
48 | }
49 |
50 | .well form .inputs{
51 | display: -webkit-flex;
52 | display: flex;
53 |
54 | #email {
55 | -webkit-flex: 1 0 auto;
56 | flex: 1 0 auto;
57 | }
58 | .btn {
59 | width: 25 * 10px;
60 | width: 25rem;
61 | margin-left: 16px;
62 | margin-left: 1rem;
63 | }
64 | }
65 |
66 | .footer {
67 | border-top: 1px solid #eee;
68 | padding-top: 2 * 16px;
69 | padding-top: 2rem;
70 | display: -webkit-flex;
71 | display: flex;
72 | p {
73 | -webkit-flex: 1 0 auto;
74 | flex: 1 0 auto;
75 | }
76 | a {
77 | padding-left: 16px;
78 | padding-left: 1rem;
79 | }
80 | }
--------------------------------------------------------------------------------
/demos/autoprefixed/css/signup.css:
--------------------------------------------------------------------------------
1 | /* Layout */
2 | body {
3 | padding: 20px 0; }
4 |
5 | .outer {
6 | max-width: 730px;
7 | margin: 0 auto; }
8 |
9 | .jumbotron {
10 | text-align: center;
11 | font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; }
12 |
13 | .plans {
14 | display: -webkit-box;
15 | display: -webkit-flex;
16 | display: -ms-flexbox;
17 | display: flex; }
18 | .plans > div {
19 | -webkit-box-flex: 1;
20 | -webkit-flex: 1 1 33%;
21 | -ms-flex: 1 1 33%;
22 | flex: 1 1 33%;
23 | display: -webkit-box;
24 | display: -webkit-flex;
25 | display: -ms-flexbox;
26 | display: flex;
27 | -webkit-box-orient: vertical;
28 | -webkit-box-direction: normal;
29 | -webkit-flex-direction: column;
30 | -ms-flex-direction: column;
31 | flex-direction: column;
32 | -webkit-box-align: start;
33 | -webkit-align-items: flex-start;
34 | -ms-flex-align: start;
35 | align-items: flex-start; }
36 | .plans > div .stretch {
37 | width: 100%;
38 | -webkit-box-flex: 1;
39 | -webkit-flex: 1 0 auto;
40 | -ms-flex: 1 0 auto;
41 | flex: 1 0 auto; }
42 | .plans > div a {
43 | margin-top: 16px;
44 | margin-top: 1rem; }
45 |
46 | .marketing {
47 | margin-bottom: 96px;
48 | margin-bottom: 6rem; }
49 |
50 | .well form .inputs {
51 | display: -webkit-box;
52 | display: -webkit-flex;
53 | display: -ms-flexbox;
54 | display: flex; }
55 | .well form .inputs #email {
56 | -webkit-box-flex: 1;
57 | -webkit-flex: 1 0 auto;
58 | -ms-flex: 1 0 auto;
59 | flex: 1 0 auto; }
60 | .well form .inputs .btn {
61 | width: 250px;
62 | width: 25rem;
63 | margin-left: 16px;
64 | margin-left: 1rem; }
65 |
66 | .footer {
67 | border-top: 1px solid #eee;
68 | padding-top: 32px;
69 | padding-top: 2rem;
70 | display: -webkit-box;
71 | display: -webkit-flex;
72 | display: -ms-flexbox;
73 | display: flex; }
74 | .footer p {
75 | -webkit-box-flex: 1;
76 | -webkit-flex: 1 0 auto;
77 | -ms-flex: 1 0 auto;
78 | flex: 1 0 auto; }
79 | .footer a {
80 | padding-left: 16px;
81 | padding-left: 1rem; }
82 |
--------------------------------------------------------------------------------
/demos/flexie/css/signup.css:
--------------------------------------------------------------------------------
1 | /* Layout */
2 | body {
3 | padding: 20px 0; }
4 |
5 | .outer {
6 | max-width: 730px;
7 | margin: 0 auto; }
8 |
9 | .jumbotron {
10 | text-align: center;
11 | font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; }
12 |
13 | .plans {
14 | display: -webkit-box;
15 | display: -webkit-flex;
16 | display: -ms-flexbox;
17 | display: flex; }
18 | .plans > div {
19 | width: 33%;
20 | -webkit-box-flex: 1;
21 | -webkit-flex: 1 1 0;
22 | -ms-flex: 1 1 0;
23 | flex: 1 1 0;
24 | display: -webkit-box;
25 | display: -webkit-flex;
26 | display: -ms-flexbox;
27 | display: flex;
28 | -webkit-box-orient: vertical;
29 | -webkit-box-direction: normal;
30 | -webkit-flex-direction: column;
31 | -ms-flex-direction: column;
32 | flex-direction: column;
33 | -webkit-box-align: start;
34 | -webkit-align-items: flex-start;
35 | -ms-flex-align: start;
36 | align-items: flex-start; }
37 | .plans > div .stretch {
38 | width: 100%;
39 | -webkit-box-flex: 1;
40 | -webkit-flex: 1 0 auto;
41 | -ms-flex: 1 0 auto;
42 | flex: 1 0 auto; }
43 | .plans > div a {
44 | margin-top: 16px;
45 | margin-top: 1rem; }
46 |
47 | .marketing {
48 | margin-bottom: 96px;
49 | margin-bottom: 6rem; }
50 |
51 | .well form .inputs {
52 | display: -webkit-box;
53 | display: -webkit-flex;
54 | display: -ms-flexbox;
55 | display: flex; }
56 | .well form .inputs #email {
57 | -webkit-box-flex: 1;
58 | -webkit-flex: 1 0 auto;
59 | -ms-flex: 1 0 auto;
60 | flex: 1 0 auto; }
61 | .well form .inputs .btn {
62 | width: 250px;
63 | width: 25rem;
64 | margin-left: 16px;
65 | margin-left: 1rem; }
66 |
67 | .footer {
68 | border-top: 1px solid #eee;
69 | padding-top: 32px;
70 | padding-top: 2rem;
71 | display: -webkit-box;
72 | display: -webkit-flex;
73 | display: -ms-flexbox;
74 | display: flex; }
75 | .footer p {
76 | -webkit-box-flex: 1;
77 | -webkit-flex: 1 0 auto;
78 | -ms-flex: 1 0 auto;
79 | flex: 1 0 auto; }
80 | .footer a {
81 | padding-left: 16px;
82 | padding-left: 1rem; }
83 |
--------------------------------------------------------------------------------
/demos/progressive_enhancement/css/signup.css:
--------------------------------------------------------------------------------
1 | /* Layout */
2 | body {
3 | padding: 20px 0; }
4 |
5 | .outer {
6 | max-width: 730px;
7 | margin: 0 auto; }
8 |
9 | .jumbotron {
10 | text-align: center;
11 | font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; }
12 |
13 | .plans {
14 | display: -webkit-box;
15 | display: -webkit-flex;
16 | display: -ms-flexbox;
17 | display: flex; }
18 | .plans > div {
19 | width: 33%;
20 | float: left;
21 | -webkit-box-flex: 1;
22 | -webkit-flex: 1 1 0;
23 | -ms-flex: 1 1 0;
24 | flex: 1 1 0;
25 | display: -webkit-box;
26 | display: -webkit-flex;
27 | display: -ms-flexbox;
28 | display: flex;
29 | -webkit-box-orient: vertical;
30 | -webkit-box-direction: normal;
31 | -webkit-flex-direction: column;
32 | -ms-flex-direction: column;
33 | flex-direction: column;
34 | -webkit-box-align: start;
35 | -webkit-align-items: flex-start;
36 | -ms-flex-align: start;
37 | align-items: flex-start; }
38 | .plans > div .stretch {
39 | width: 100%;
40 | -webkit-box-flex: 1;
41 | -webkit-flex: 1 1 auto;
42 | -ms-flex: 1 1 auto;
43 | flex: 1 1 auto; }
44 | .plans > div a {
45 | margin-top: 16px;
46 | margin-top: 1rem; }
47 |
48 | .marketing {
49 | margin-bottom: 96px;
50 | margin-bottom: 6rem; }
51 |
52 | .well form .inputs {
53 | display: -webkit-box;
54 | display: -webkit-flex;
55 | display: -ms-flexbox;
56 | display: flex; }
57 | .well form .inputs #email {
58 | width: 50%;
59 | display: inline;
60 | -webkit-box-flex: 1;
61 | -webkit-flex: 1 0 auto;
62 | -ms-flex: 1 0 auto;
63 | flex: 1 0 auto; }
64 | .well form .inputs .btn {
65 | width: 250px;
66 | width: 25rem;
67 | margin-left: 16px;
68 | margin-left: 1rem; }
69 |
70 | .footer {
71 | border-top: 1px solid #eee;
72 | padding-top: 32px;
73 | padding-top: 2rem;
74 | display: -webkit-box;
75 | display: -webkit-flex;
76 | display: -ms-flexbox;
77 | display: flex; }
78 | .footer p {
79 | float: left;
80 | -webkit-box-flex: 1;
81 | -webkit-flex: 1 0 auto;
82 | -ms-flex: 1 0 auto;
83 | flex: 1 0 auto; }
84 | .footer > a {
85 | float: right;
86 | padding-left: 16px;
87 | padding-left: 1rem; }
88 |
--------------------------------------------------------------------------------
/Gruntfile.js:
--------------------------------------------------------------------------------
1 | /*global module:false*/
2 | module.exports = function(grunt) {
3 |
4 | // Project configuration.
5 | grunt.initConfig({
6 | // Metadata.
7 | pkg: grunt.file.readJSON('package.json'),
8 | banner: '/*! <%= pkg.title || pkg.name %> - v<%= pkg.version %> - ' +
9 | '<%= grunt.template.today("yyyy-mm-dd") %>\n' +
10 | '<%= pkg.homepage ? "* " + pkg.homepage + "\\n" : "" %>' +
11 | '* Copyright (c) <%= grunt.template.today("yyyy") %> <%= pkg.author.name %>;' +
12 | ' Licensed <%= _.pluck(pkg.licenses, "type").join(", ") %> */\n',
13 | // Task configuration.
14 | concat: {
15 | options: {
16 | banner: '<%= banner %>',
17 | stripBanners: true
18 | },
19 | dist: {
20 | src: ['lib/<%= pkg.name %>.js'],
21 | dest: 'dist/<%= pkg.name %>.js'
22 | }
23 | },
24 | uglify: {
25 | options: {
26 | banner: '<%= banner %>'
27 | },
28 | dist: {
29 | src: '<%= concat.dist.dest %>',
30 | dest: 'dist/<%= pkg.name %>.min.js'
31 | }
32 | },
33 | jshint: {
34 | options: {
35 | curly: true,
36 | eqeqeq: true,
37 | immed: true,
38 | latedef: true,
39 | newcap: true,
40 | noarg: true,
41 | sub: true,
42 | undef: true,
43 | unused: true,
44 | boss: true,
45 | eqnull: true,
46 | browser: true,
47 | globals: {}
48 | },
49 | gruntfile: {
50 | src: 'Gruntfile.js'
51 | },
52 | lib_test: {
53 | src: ['lib/**/*.js', 'test/**/*.js']
54 | }
55 | },
56 | qunit: {
57 | files: ['test/**/*.html']
58 | },
59 | autoprefixer: {
60 | // prefix all files
61 | multiple_files: {
62 | expand: true,
63 | flatten: true,
64 | src: '*.css',
65 | dest: 'css/'
66 | }
67 | },
68 | sass: {
69 | dist: {
70 | files: {
71 | 'signup.css': 'signup.scss'
72 | }
73 | }
74 | },
75 | watch: {
76 | sass: {
77 | files: ['*.scss'],
78 | tasks: ['sass', 'autoprefixer'],
79 | options: {
80 | spawn: false,
81 | livereload: true
82 | }
83 | },
84 | html: {
85 | files: ['*.html'],
86 | options: {
87 | spawn: false,
88 | livereload: true
89 | }
90 | }
91 | }
92 | });
93 |
94 | // These plugins provide necessary tasks.
95 | grunt.loadNpmTasks('grunt-contrib-watch');
96 | grunt.loadNpmTasks('grunt-autoprefixer');
97 | grunt.loadNpmTasks('grunt-sass');
98 |
99 | // Default task.
100 | grunt.registerTask('default', ['watch', 'autoprefixer', 'sass']);
101 |
102 | };
103 |
--------------------------------------------------------------------------------
/demos/latest_syntax_only/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 | Pagesnap - Take monthly screenshots of any URL
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
Pagesnap
25 |
Take monthly screenshots of any URL - automatically
26 |
27 |
28 |
29 |
30 |
Basic
31 |
$10 $5 per year
32 |
Monthly snaps
33 |
Up to two URLs
34 |
Perfect for occasional bloggers
35 |
Start Now
36 |
37 |
38 |
Pro
39 |
$59 $49 per year
40 |
Daily, Weekly or Monthly snaps
41 |
Up to 50 URLs
42 |
Great for professional blogs, news sites, and more
43 |
Start Now
44 |
45 |
46 |
Business
47 |
$299 $249 per year
48 |
Daily, Weekly or Monthly snaps
49 |
Up to 500 URLs
50 |
Designed with business and agencies in mind. Upsell your clients by giving them a piece of their history.
51 |
Start Now
52 |
53 |
54 |
55 |
56 |
57 |
Signup
58 |
We're not quite ready for people to sign up yet. If you'd like to get an email when we go live, put your address in below.
59 |
60 |
67 |
We won't send you spam. Unsubscribe at any time.
68 |
69 |
70 |
71 |
72 |
78 |
79 |
80 |
81 |
82 |
--------------------------------------------------------------------------------
/demos/autoprefixed/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 | Pagesnap - Take monthly screenshots of any URL
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
Pagesnap
29 |
Take monthly screenshots of any URL - automatically
30 |
31 |
32 |
33 |
34 |
Basic
35 |
$10 $5 per year
36 |
Monthly snaps
37 |
Up to two URLs
38 |
Perfect for occasional bloggers
39 |
Start Now
40 |
41 |
42 |
Pro
43 |
$59 $49 per year
44 |
Daily, Weekly or Monthly snaps
45 |
Up to 50 URLs
46 |
Great for professional blogs, news sites, and more
47 |
Start Now
48 |
49 |
50 |
Business
51 |
$299 $249 per year
52 |
Daily, Weekly or Monthly snaps
53 |
Up to 500 URLs
54 |
Designed with business and agencies in mind. Upsell your clients by giving them a piece of their history.
55 |
Start Now
56 |
57 |
58 |
59 |
60 |
61 |
Signup
62 |
We're not quite ready for people to sign up yet. If you'd like to get an email when we go live, put your address in below.
63 |
64 |
71 |
We won't send you spam. Unsubscribe at any time.
72 |
73 |
74 |
75 |
76 |
82 |
83 |
84 |
85 |
86 |
--------------------------------------------------------------------------------
/demos/progressive_enhancement/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 | Pagesnap - Take monthly screenshots of any URL
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
Pagesnap
29 |
Take monthly screenshots of any URL - automatically
30 |
31 |
32 |
33 |
34 |
Basic
35 |
$10 $5 per year
36 |
Monthly snaps
37 |
Up to two URLs
38 |
Perfect for occasional bloggers
39 |
Start Now
40 |
41 |
42 |
Pro
43 |
$59 $49 per year
44 |
Daily, Weekly or Monthly snaps
45 |
Up to 50 URLs
46 |
Great for professional blogs, news sites, and more
47 |
Start Now
48 |
49 |
50 |
Business
51 |
$299 $249 per year
52 |
Daily, Weekly or Monthly snaps
53 |
Up to 500 URLs
54 |
Designed with business and agencies in mind. Upsell your clients by giving them a piece of their history.
55 |
Start Now
56 |
57 |
58 |
59 |
60 |
61 |
Signup
62 |
We're not quite ready for people to sign up yet. If you'd like to get an email when we go live, put your address in below.
63 |
64 |
71 |
We won't send you spam. Unsubscribe at any time.
72 |
73 |
74 |
75 |
76 |
82 |
83 |
84 |
85 |
86 |
--------------------------------------------------------------------------------
/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 | Pagesnap - Take monthly screenshots of any URL
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
Pagesnap
31 |
Take monthly screenshots of any URL - automatically
32 |
33 |
34 |
35 |
36 |
Basic
37 |
$10 $5 per year
38 |
Monthly snaps
39 |
Up to two URLs
40 |
Perfect for occasional bloggers
41 |
Start Now
42 |
43 |
44 |
Pro
45 |
$59 $49 per year
46 |
Daily, Weekly or Monthly snaps
47 |
Up to 50 URLs
48 |
Great for professional blogs, news sites, and more
49 |
Start Now
50 |
51 |
52 |
Business
53 |
$299 $249 per year
54 |
Daily, Weekly or Monthly snaps
55 |
Up to 500 URLs
56 |
Designed with business and agencies in mind. Upsell your clients by giving them a piece of their history.
57 |
Start Now
58 |
59 |
60 |
61 |
62 |
63 |
Signup
64 |
We're not quite ready for people to sign up yet. If you'd like to get an email when we go live, put your address in below.
65 |
66 |
73 |
We won't send you spam. Unsubscribe at any time.
74 |
75 |
76 |
77 |
78 |
84 |
85 |
86 |
87 |
88 |
--------------------------------------------------------------------------------
/demos/flexie/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 | Pagesnap - Take monthly screenshots of any URL
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
Pagesnap
31 |
Take monthly screenshots of any URL - automatically
32 |
33 |
34 |
35 |
36 |
Basic
37 |
$10 $5 per year
38 |
Monthly snaps
39 |
Up to two URLs
40 |
Perfect for occasional bloggers
41 |
Start Now
42 |
43 |
44 |
Pro
45 |
$59 $49 per year
46 |
Daily, Weekly or Monthly snaps
47 |
Up to 50 URLs
48 |
Great for professional blogs, news sites, and more
49 |
Start Now
50 |
51 |
52 |
Business
53 |
$299 $249 per year
54 |
Daily, Weekly or Monthly snaps
55 |
Up to 500 URLs
56 |
Designed with business and agencies in mind. Upsell your clients by giving them a piece of their history.
57 |
Start Now
58 |
59 |
60 |
61 |
62 |
63 |
Signup
64 |
We're not quite ready for people to sign up yet. If you'd like to get an email when we go live, put your address in below.
65 |
66 |
73 |
We won't send you spam. Unsubscribe at any time.
74 |
75 |
76 |
77 |
78 |
84 |
85 |
86 |
87 |
88 |
--------------------------------------------------------------------------------
/flexie.js:
--------------------------------------------------------------------------------
1 | /*
2 | File: flexie.js
3 |
4 | About: Version
5 | 1.0.3
6 |
7 | Project: Flexie
8 |
9 | Description:
10 | Legacy support for the CSS3 Flexible Box Model
11 |
12 | License:
13 | The MIT License
14 |
15 | Copyright (c) 2010 Richard Herrera
16 |
17 | Permission is hereby granted, free of charge, to any person obtaining a copy
18 | of this software and associated documentation files (the "Software"), to deal
19 | in the Software without restriction, including without limitation the rights
20 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
21 | copies of the Software, and to permit persons to whom the Software is
22 | furnished to do so, subject to the following conditions:
23 |
24 | The above copyright notice and this permission notice shall be included in
25 | all copies or substantial portions of the Software.
26 |
27 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
28 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
29 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
30 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
31 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
32 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
33 | THE SOFTWARE.
34 | */
35 |
36 | /*
37 | Class: Flexie
38 | Scoped to the Flexie Global Namespace
39 | */
40 |
41 | /*jslint evil: true, regexp: false, plusplus: false */
42 | /*global window, document */
43 |
44 | var Flexie = (function (win, doc) {
45 |
46 | // Scope public properties
47 | var FLX = {},
48 |
49 | // Each Flexie-modified DOM node gets a unique identifier
50 | FLX_DOM_ID = 0,
51 | FLX_DOM_ATTR = "data-flexie-id",
52 | FLX_PARENT_ATTR = "data-flexie-parent",
53 |
54 | // Store support for flexbox
55 | SUPPORT,
56 |
57 | // Store reference to engine
58 | ENGINE,
59 |
60 | ENGINES = {
61 | "NW" : {
62 | s : "*.Dom.select"
63 | },
64 | "DOMAssistant" : {
65 | s : "*.$",
66 | m : "*.DOMReady"
67 | },
68 | "Prototype" : {
69 | s : "$$",
70 | m : "document.observe",
71 | p : "dom:loaded",
72 | c : "document"
73 | },
74 | "YAHOO" : {
75 | s : "*.util.Selector.query",
76 | m : "*.util.Event.onDOMReady",
77 | c : "*.util.Event"
78 | },
79 | "MooTools" : {
80 | s : "$$",
81 | m : "window.addEvent",
82 | p : "domready"
83 | },
84 | "Sizzle" : {
85 | s : "*"
86 | },
87 | "jQuery" : {
88 | s : "*",
89 | m : "*(document).ready"
90 | },
91 | "dojo" : {
92 | s : "*.query",
93 | m : "*.addOnLoad"
94 | }
95 | },
96 |
97 | // Store reference to library
98 | LIBRARY,
99 |
100 | // Regular Expressions
101 | PIXEL = /^-?\d+(?:px)?$/i,
102 | NUMBER = /^-?\d/,
103 | SIZES = /width|height|margin|padding|border/,
104 | MSIE = /(msie) ([\w.]+)/,
105 | WHITESPACE_CHARACTERS = /\t|\n|\r/g,
106 | RESTRICTIVE_PROPERTIES = /^max\-([a-z]+)/,
107 | PROTOCOL = /^https?:\/\//i,
108 | LEADINGTRIM = /^\s\s*/,
109 | TRAILINGTRIM = /\s\s*$/,
110 | ONLY_WHITESPACE = /^\s*$/,
111 | CSS_SELECTOR = /\s?(\#|\.|\[|\:(\:)?[^first\-(line|letter)|before|after]+)/g,
112 |
113 | // String constants
114 | EMPTY_STRING = "",
115 | SPACE_STRING = " ",
116 | PLACEHOLDER_STRING = "$1",
117 | PADDING_RIGHT = "paddingRight",
118 | PADDING_BOTTOM = "paddingBottom",
119 | PADDING_LEFT = "paddingLeft",
120 | PADDING_TOP = "paddingTop",
121 | BORDER_RIGHT = "borderRightWidth",
122 | BORDER_BOTTOM = "borderBottomWidth",
123 | BORDER_LEFT = "borderLeftWidth",
124 | BORDER_TOP = "borderTopWidth",
125 | HORIZONTAL = "horizontal",
126 | VERTICAL = "vertical",
127 | INLINE_AXIS = "inline-axis",
128 | BLOCK_AXIS = "block-axis",
129 | INHERIT = "inherit",
130 | LEFT = "left",
131 |
132 | END_MUSTACHE = "}",
133 |
134 | PREFIXES = " -o- -moz- -ms- -webkit- -khtml- ".split(SPACE_STRING),
135 |
136 | DEFAULTS = {
137 | orient : HORIZONTAL,
138 | align : "stretch",
139 | direction : INHERIT,
140 | pack : "start"
141 | },
142 |
143 | // Global reference objects
144 | FLEX_BOXES = [],
145 | POSSIBLE_FLEX_CHILDREN = [],
146 | DOM_ORDERED,
147 |
148 | RESIZE_LISTENER,
149 |
150 | // Minification optimizations
151 | TRUE = true,
152 | FALSE = false,
153 | NULL = null,
154 | UNDEFINED,
155 |
156 | // If IE, which version?
157 | BROWSER = {
158 | IE : (function () {
159 | var ie, ua = win.navigator.userAgent,
160 | match = (MSIE).exec(ua.toLowerCase());
161 |
162 | if (match) {
163 | ie = parseInt(match[2], 10);
164 | }
165 |
166 | return ie;
167 | }())
168 | },
169 |
170 | /*
171 | selectivizr v1.0.0 - (c) Keith Clark, freely distributable under the terms
172 | of the MIT license.
173 |
174 | selectivizr.com
175 | */
176 | selectivizrEngine;
177 |
178 | function trim (string) {
179 | if (string) {
180 | string = string.replace(LEADINGTRIM, EMPTY_STRING).replace(TRAILINGTRIM, EMPTY_STRING);
181 | }
182 |
183 | return string;
184 | }
185 |
186 | // --[ determineSelectorMethod() ]--------------------------------------
187 | // walks through the engines object testing for an suitable
188 | // selector engine.
189 |
190 | // Moving outside Selectivizr scope because detection is needed before running selectivizrEngine
191 | function determineSelectorMethod() {
192 | // compatiable selector engines in order of CSS3 support
193 | var engines = ENGINES, method,
194 | engine, obj;
195 |
196 | for (engine in engines) {
197 | if (engines.hasOwnProperty(engine)) {
198 | obj = engines[engine];
199 |
200 | if (win[engine] && !method) {
201 | method = eval(obj.s.replace("*", engine));
202 |
203 | if (method) {
204 | ENGINE = engine;
205 | break;
206 | }
207 | }
208 | }
209 | }
210 |
211 | return method;
212 | }
213 |
214 | // Event handler for onload/onresize events
215 | function addEvent(type, func) {
216 | type = "on" + type;
217 | var oldevent = win[type];
218 |
219 | if (typeof win[type] !== "function") {
220 | win[type] = func;
221 | } else {
222 | win[type] = function () {
223 | if (oldevent) {
224 | oldevent();
225 | }
226 | func();
227 | };
228 | }
229 | }
230 |
231 | function attachLoadMethod(handler) {
232 | if (!ENGINE) {
233 | LIBRARY = determineSelectorMethod();
234 | }
235 |
236 | // compatiable selector engines in order of CSS3 support
237 | var engines = ENGINES,
238 | method, caller, args,
239 | engine, obj;
240 |
241 | for (engine in engines) {
242 | if (engines.hasOwnProperty(engine)) {
243 | obj = engines[engine];
244 |
245 | if (win[engine] && !method && obj.m) {
246 | method = eval(obj.m.replace("*", engine));
247 | caller = obj.c ? eval(obj.c.replace("*", engine)) : win;
248 | args = [];
249 |
250 | if (method && caller) {
251 | if (obj.p) {
252 | args.push(obj.p);
253 | }
254 | args.push(handler);
255 | method.apply(caller, args);
256 | break;
257 | }
258 | }
259 | }
260 | }
261 |
262 | if (!method) {
263 | addEvent("load", handler);
264 | }
265 | }
266 |
267 | function buildSelector (node) {
268 | var selector = node.nodeName.toLowerCase();
269 |
270 | if (node.id) {
271 | selector += "#" + node.id;
272 | } else if (node.FLX_DOM_ID) {
273 | selector += "[" + FLX_DOM_ATTR + "='" + node.FLX_DOM_ID + "']";
274 | }
275 |
276 | return selector;
277 | }
278 |
279 | function setFlexieId (node) {
280 | if (!node.FLX_DOM_ID) {
281 | FLX_DOM_ID = (FLX_DOM_ID + 1);
282 |
283 | node.FLX_DOM_ID = FLX_DOM_ID;
284 | node.setAttribute(FLX_DOM_ATTR, node.FLX_DOM_ID);
285 | }
286 | }
287 |
288 | function buildSelectorTree(text) {
289 | var rules = [], ruletext, rule,
290 | match, selector, proptext, splitprop, properties,
291 | i, j, x;
292 |
293 | // Tabs, Returns
294 | text = text.replace(WHITESPACE_CHARACTERS, EMPTY_STRING);
295 |
296 | // Leading / Trailing Whitespace
297 | text = text.replace(/\s?(\{|\:|\})\s?/g, PLACEHOLDER_STRING);
298 |
299 | ruletext = text.split(END_MUSTACHE);
300 |
301 | for (i in ruletext) {
302 | if (ruletext.hasOwnProperty(i)) {
303 | text = ruletext[i];
304 |
305 | if (text) {
306 | rule = [text, END_MUSTACHE].join(EMPTY_STRING);
307 |
308 | match = (/(\@media[^\{]+\{)?(.*)\{(.*)\}/).exec(rule);
309 |
310 | if (match && match[3]) {
311 | selector = match[2];
312 | proptext = match[3].split(";");
313 | properties = [];
314 |
315 | for (j in proptext) {
316 | if (proptext.hasOwnProperty(j)) {
317 | x = proptext[j];
318 | splitprop = x.split(":");
319 |
320 | if (splitprop.length && splitprop[1]) {
321 | properties.push({
322 | property : splitprop[0],
323 | value : splitprop[1]
324 | });
325 | }
326 | }
327 | }
328 |
329 | if (selector && properties.length) {
330 | rules.push({
331 | selector : selector,
332 | properties : properties
333 | });
334 | }
335 | }
336 | }
337 | }
338 | }
339 |
340 | return rules;
341 | }
342 |
343 | function findFlexboxElements(rules) {
344 | var selectors, properties,
345 | property, value, shortProp,
346 | selectorSplit = /\s?,\s?/,
347 | createUniqueObject, addRules, key,
348 | uniqueChildren = {}, uniqueBoxes = {},
349 | i, j, rule, k, l, selector, m, n, prop;
350 |
351 | createUniqueObject = function (selector, rules, prop, value) {
352 | var unique, i, j, rule;
353 |
354 | unique = {
355 | selector : trim(selector),
356 | properties : []
357 | };
358 |
359 | for (i = 0, j = rules.properties.length; i < j; i++) {
360 | rule = rules.properties[i];
361 |
362 | unique.properties.push({
363 | property : trim(rule.property),
364 | value : trim(rule.value)
365 | });
366 | }
367 |
368 | if (prop && value) {
369 | unique[prop] = value;
370 | }
371 |
372 | return unique;
373 | };
374 |
375 | addRules = function (selector, rules, prop, value) {
376 | var box = (prop && value) ? uniqueChildren[selector] : uniqueBoxes[selector],
377 | exists, x, i, j, rule, k, l;
378 |
379 | if (box) {
380 | for (i = 0, j = rules.properties.length; i < j; i++) {
381 | rule = rules.properties[i];
382 |
383 | for (k = 0, l = box.properties.length; k < l; k++) {
384 | x = box.properties[k];
385 |
386 | if (rule.property === x.property) {
387 | exists = k;
388 | return false;
389 | }
390 | }
391 |
392 | if (exists) {
393 | box.properties[exists] = rule;
394 | } else {
395 | box.properties.push(rule);
396 | }
397 | }
398 |
399 | if (prop && value) {
400 | box[prop] = value;
401 | }
402 | } else {
403 | if (prop && value) {
404 | uniqueChildren[selector] = createUniqueObject(selector, rules, prop, value);
405 | } else {
406 | uniqueBoxes[selector] = createUniqueObject(selector, rules, NULL, NULL);
407 | }
408 | }
409 | };
410 |
411 | for (i = 0, j = rules.length; i < j; i++) {
412 | rule = rules[i];
413 |
414 | selectors = trim(rule.selector).replace(selectorSplit, ",").split(selectorSplit);
415 |
416 | for (k = 0, l = selectors.length; k < l; k++) {
417 | selector = trim(selectors[k]);
418 | properties = rule.properties;
419 |
420 | for (m = 0, n = properties.length; m < n; m++) {
421 | prop = properties[m];
422 | property = trim(prop.property);
423 | value = trim(prop.value);
424 |
425 | // if you use the new syntax along with the old
426 | if (property && property !== "flex") {
427 |
428 | shortProp = property.replace("box-", EMPTY_STRING);
429 | shortProp = property.replace("-webkit-box-", EMPTY_STRING);
430 |
431 | switch (shortProp) {
432 | case "display" :
433 | if (value === "box" || value === "-webkit-box") {
434 | addRules(selector, rule, NULL, NULL);
435 | }
436 | break;
437 |
438 | case "orient" :
439 | case "align" :
440 | case "direction" :
441 | case "pack" :
442 | addRules(selector, rule, NULL, NULL);
443 | break;
444 |
445 | case "flex" :
446 | case "flex-group" :
447 | case "ordinal-group" :
448 | addRules(selector, rule, shortProp, value);
449 | break;
450 | }
451 | }
452 | }
453 | }
454 | }
455 |
456 | for (key in uniqueBoxes) {
457 | if (uniqueBoxes.hasOwnProperty(key)) {
458 | FLEX_BOXES.push(uniqueBoxes[key]);
459 | }
460 | }
461 |
462 | for (key in uniqueChildren) {
463 | if (uniqueChildren.hasOwnProperty(key)) {
464 | POSSIBLE_FLEX_CHILDREN.push(uniqueChildren[key]);
465 | }
466 | }
467 |
468 | return {
469 | boxes : FLEX_BOXES,
470 | children : POSSIBLE_FLEX_CHILDREN
471 | };
472 | }
473 |
474 | function matchFlexChildren(parent, lib, possibleChildren) {
475 | var caller, unique, matches = [],
476 | i, j, child,
477 | k, l, node,
478 | key;
479 |
480 | for (i = 0, j = possibleChildren.length; i < j; i++) {
481 | child = possibleChildren[i];
482 |
483 | if (child.selector) {
484 | caller = lib(child.selector);
485 | caller = caller[0] ? caller : [caller];
486 |
487 | if (caller[0]) {
488 |
489 | for (k = 0, l = caller.length; k < l; k++) {
490 | node = caller[k];
491 |
492 | if (node.nodeName !== UNDEFINED) {
493 | switch (node.nodeName.toLowerCase()) {
494 | case "script" :
495 | case "style" :
496 | case "link" :
497 | break;
498 |
499 | default :
500 | if (node.parentNode === parent) {
501 | // Flag each unique node with FLX_DOM_ID
502 | setFlexieId(node);
503 |
504 | unique = {};
505 |
506 | for (key in child) {
507 | if (child.hasOwnProperty(key)) {
508 | unique[key] = child[key];
509 | }
510 | }
511 |
512 | unique.match = node;
513 | matches.push(unique);
514 | }
515 | break;
516 | }
517 | }
518 | }
519 | }
520 | } else {
521 | // Flag each unique node with FLX_DOM_ID
522 | setFlexieId(child);
523 |
524 | matches.push({
525 | match : child,
526 | selector : buildSelector(child)
527 | });
528 | }
529 | }
530 |
531 | return matches;
532 | }
533 |
534 | function getParams(params) {
535 | var key;
536 |
537 | for (key in params) {
538 | if (params.hasOwnProperty(key)) {
539 | params[key] = params[key] || DEFAULTS[key];
540 | }
541 | }
542 |
543 | return params;
544 | }
545 |
546 | function buildFlexieCall(flexers) {
547 | var selector, properties, property, value, shortProp,
548 | display, orient, align, direction, pack,
549 | lib, caller, children,
550 | box, params, flexboxes = {},
551 | match, childMatch, nestedFlexboxes,
552 | flexieParentSelector = "[" + FLX_PARENT_ATTR + "]",
553 | i, j, flex, k, l, prop,
554 | target, key, m, n, child, o, p, existing;
555 |
556 | // No boxflex? No dice.
557 | if (!flexers) {
558 | return;
559 | }
560 |
561 | for (i = 0, j = flexers.boxes.length; i < j; i++) {
562 | flex = flexers.boxes[i];
563 | flex.selector = trim(flex.selector);
564 |
565 | selector = flex.selector;
566 | properties = flex.properties;
567 |
568 | display = orient = align = direction = pack = NULL;
569 |
570 | for (k = 0, l = properties.length; k < l; k++) {
571 | prop = properties[k];
572 |
573 | property = trim(prop.property);
574 | value = trim(prop.value);
575 |
576 | if (property && property !== "flex") {
577 | shortProp = property.replace("box-", EMPTY_STRING);
578 | shortProp = property.replace("-webkit-box-", EMPTY_STRING);
579 |
580 | switch (shortProp) {
581 | case "display" :
582 | if (value === "box" || value === "-webkit-box") {
583 | display = "box";
584 | }
585 | break;
586 |
587 | case "orient" :
588 | orient = value;
589 | break;
590 |
591 | case "align" :
592 | align = value;
593 | break;
594 |
595 | case "direction" :
596 | direction = value;
597 | break;
598 |
599 | case "pack" :
600 | pack = value;
601 | break;
602 | }
603 | }
604 | }
605 |
606 | // Determine library
607 | lib = LIBRARY;
608 |
609 | // Call it.
610 | caller = lib(flex.selector);
611 |
612 | // In an array?
613 | caller = caller[0] ? caller : [caller];
614 |
615 | for (k = 0, l = caller.length; k < l; k++) {
616 | target = caller[k];
617 |
618 | // If is DOM object
619 | if (target.nodeType) {
620 | // Flag each unique node with FLX_DOM_ID
621 | setFlexieId(target);
622 |
623 | // Find possible child node matches
624 | children = matchFlexChildren(target, lib, flexers.children);
625 |
626 | // Find any nested flexbox elements
627 | nestedFlexboxes = selector + " " + flexieParentSelector;
628 |
629 | // Make sure there is some value associated with box properties
630 | params = {
631 | target : target,
632 | selector : selector,
633 | properties : properties,
634 | children : children,
635 | display : display,
636 | orient : orient,
637 | align : align,
638 | direction: direction,
639 | pack : pack,
640 | nested : nestedFlexboxes
641 | };
642 |
643 | match = flexboxes[target.FLX_DOM_ID];
644 |
645 | if (match) {
646 | for (key in params) {
647 | if (params.hasOwnProperty(key)) {
648 | value = params[key];
649 |
650 | switch (key) {
651 | case "selector" :
652 | if (value && !(new RegExp(value).test(match[key]))) {
653 | match[key] += ", " + value;
654 | }
655 | break;
656 |
657 | case "children" :
658 | for (m = 0, n = params[key].length; m < n; m++) {
659 | child = params[key][m];
660 | childMatch = FALSE;
661 |
662 | for (o = 0, p = match[key].length; o < p; o++) {
663 | existing = match[key][o];
664 |
665 | if (child.match.FLX_DOM_ID === existing.match.FLX_DOM_ID) {
666 | childMatch = TRUE;
667 | }
668 | }
669 |
670 | if (!childMatch) {
671 | match[key].push(child);
672 | }
673 | }
674 | break;
675 |
676 | default :
677 | if (value) {
678 | match[key] = value;
679 | }
680 | break;
681 | }
682 | }
683 | }
684 | } else {
685 | flexboxes[target.FLX_DOM_ID] = getParams(params);
686 | flexboxes[target.FLX_DOM_ID].target.setAttribute(FLX_PARENT_ATTR, TRUE);
687 | }
688 | }
689 | }
690 | }
691 |
692 | DOM_ORDERED = LIBRARY(flexieParentSelector);
693 | FLEX_BOXES = {};
694 |
695 | for (i = 0, j = DOM_ORDERED.length; i < j; i++) {
696 | target = DOM_ORDERED[i];
697 |
698 | FLEX_BOXES[target.FLX_DOM_ID] = flexboxes[target.FLX_DOM_ID];
699 | }
700 |
701 | // Loop through each match, initialize constructor
702 | for (key in FLEX_BOXES) {
703 | if (FLEX_BOXES.hasOwnProperty(key)) {
704 | flex = FLEX_BOXES[key];
705 |
706 | // One final check to ensure each flexbox has a display property
707 | if (flex.display === "box") {
708 | // Constructor
709 | box = new FLX.box(flex);
710 | }
711 | }
712 | }
713 | }
714 |
715 | function calcPx(element, props, dir) {
716 | var dim = dir.replace(dir.charAt(0), dir.charAt(0).toUpperCase()),
717 | value = element["offset" + dim] || 0,
718 | i, j, prop;
719 |
720 | if (value) {
721 | for (i = 0, j = props.length; i < j; i++) {
722 | prop = parseFloat(element.currentStyle[props[i]]);
723 |
724 | if (!isNaN(prop)) {
725 | value -= prop;
726 | }
727 | }
728 | }
729 |
730 | return value;
731 | }
732 |
733 | function getTrueValue(element, name) {
734 | var left, rsLeft,
735 | ret = element.currentStyle && element.currentStyle[name],
736 | style = element.style;
737 |
738 | if (!PIXEL.test(ret) && NUMBER.test(ret)) {
739 |
740 | // Remember the original values
741 | left = style.left;
742 | rsLeft = element.runtimeStyle.left;
743 |
744 | // Put in the new values to get a computed value out
745 | element.runtimeStyle.left = element.currentStyle.left;
746 | style.left = ret || 0;
747 | ret = style.pixelLeft + "px";
748 |
749 | // Revert the changed values
750 | style.left = left || 0;
751 | element.runtimeStyle.left = rsLeft;
752 | }
753 |
754 | return ret;
755 | }
756 |
757 | function unAuto(element, prop, name) {
758 | var props;
759 |
760 | switch (name) {
761 | case "width" :
762 | props = [PADDING_LEFT, PADDING_RIGHT, BORDER_LEFT, BORDER_RIGHT];
763 | prop = calcPx(element, props, name);
764 | break;
765 |
766 | case "height" :
767 | props = [PADDING_TOP, PADDING_BOTTOM, BORDER_TOP, BORDER_BOTTOM];
768 | prop = calcPx(element, props, name);
769 | break;
770 |
771 | default :
772 | prop = getTrueValue(element, name);
773 | break;
774 | }
775 |
776 | return prop;
777 | }
778 |
779 | function getPixelValue(element, prop, name) {
780 | if (PIXEL.test(prop)) {
781 | return prop;
782 | }
783 |
784 | // if property is auto, do some messy appending
785 | if (prop === "auto" || prop === "medium") {
786 | prop = unAuto(element, prop, name);
787 | } else {
788 | prop = getTrueValue(element, name);
789 | }
790 |
791 | return prop;
792 | }
793 |
794 | function getComputedStyle(element, property, returnAsInt) {
795 | var value;
796 |
797 | if (element === UNDEFINED) {
798 | return;
799 | }
800 |
801 | if (win.getComputedStyle) {
802 | value = win.getComputedStyle(element, NULL)[property];
803 | } else {
804 | if (SIZES.test(property)) {
805 | value = getPixelValue(element, (element && element.currentStyle) ? element.currentStyle[property] : 0, property);
806 | } else {
807 | value = element.currentStyle[property];
808 | }
809 | }
810 |
811 | if (returnAsInt) {
812 | value = parseInt(value, 10);
813 |
814 | if (isNaN(value)) {
815 | value = 0;
816 | }
817 | }
818 |
819 | return value;
820 | }
821 |
822 | function clientWidth(element) {
823 | return element.innerWidth || element.clientWidth;
824 | }
825 |
826 | function clientHeight(element) {
827 | return element.innerHeight || element.clientHeight;
828 | }
829 |
830 | function appendProperty(target, prop, value, prefixName) {
831 | var cssText = [],
832 | i, j, prefix;
833 |
834 | for (i = 0, j = PREFIXES.length; i < j; i++) {
835 | prefix = PREFIXES[i];
836 | cssText.push((prefixName ? prefix : EMPTY_STRING) + prop + ":" + (!prefixName ? prefix : EMPTY_STRING) + value);
837 | }
838 |
839 | target.style.cssText += cssText.join(";");
840 | return target;
841 | }
842 |
843 | function appendPixelValue(target, prop, value) {
844 | var targets = target && target[0] ? target : [target],
845 | i, j;
846 |
847 | for (i = 0, j = targets.length; i < j; i++) {
848 | target = targets[i];
849 |
850 | if (target && target.style) {
851 | target.style[prop] = (value ? (value + "px") : EMPTY_STRING);
852 | }
853 | }
854 | }
855 |
856 | function calculateSpecificity (selector) {
857 | var selectorGrid, matrix, total,
858 | i, j, chunk;
859 |
860 | selectorGrid = selector.replace(CSS_SELECTOR, function (e, f) {
861 | return "%" + f;
862 | }).replace(/\s|\>|\+|\~/g, "%").split(/%/g);
863 |
864 | matrix = {
865 | _id : 100,
866 | _class : 10,
867 | _tag : 1
868 | };
869 |
870 | // Start with rule index position
871 | total = 0;
872 |
873 | // Add each selector value to total.
874 | for (i = 0, j = selectorGrid.length; i < j; i++) {
875 | chunk = selectorGrid[i];
876 |
877 | if ((/#/).test(chunk)) {
878 | total += matrix._id;
879 | } else if ((/\.|\[|\:/).test(chunk)) {
880 | total += matrix._class;
881 | } else if ((/[a-zA-Z]+/).test(chunk)) {
882 | total += matrix._tag;
883 | }
884 | }
885 |
886 | return total;
887 | }
888 |
889 | function filterDuplicates (matches, children, type) {
890 | var filteredMatches = [], exists,
891 | spec = (type ? "ordinal" : "flex") + "Specificity",
892 | i, j, x, k, l, f;
893 |
894 | for (i = 0, j = matches.length; i < j; i++) {
895 | x = matches[i];
896 |
897 | if ((!type && x.flex) || (type && x["ordinal-group"])) {
898 | x[spec] = x[spec] || calculateSpecificity(x.selector);
899 |
900 | exists = FALSE;
901 |
902 | for (k = 0, l = filteredMatches.length; k < l; k++) {
903 | f = filteredMatches[k];
904 |
905 | if (f.match === x.match) {
906 | if (f[spec] < x[spec]) {
907 | filteredMatches[j] = x;
908 | }
909 |
910 | exists = TRUE;
911 | return FALSE;
912 | }
913 | }
914 |
915 | if (!exists) {
916 | filteredMatches.push(x);
917 | }
918 | }
919 | }
920 |
921 | return filteredMatches;
922 | }
923 |
924 | function createMatchMatrix(matches, children, type) {
925 | var groups = {}, keys = [], totalRatio = 0,
926 | group, order = "ordinal-group",
927 | BoxOrdinalAttr = "data-" + order,
928 | i, j, kid, k, l, x, key;
929 |
930 | // Filter dupes
931 | matches = filterDuplicates(matches, children, type);
932 |
933 | for (i = 0, j = children.length; i < j; i++) {
934 | kid = children[i];
935 |
936 | for (k = 0, l = matches.length; k < l; k++) {
937 | x = matches[k];
938 |
939 | if (type) {
940 | // If no value declared, it's the default.
941 | group = x[order] || "1";
942 |
943 | if (x.match === kid) {
944 | x.match.setAttribute(BoxOrdinalAttr, group);
945 |
946 | groups[group] = groups[group] || [];
947 | groups[group].push(x);
948 | }
949 | } else {
950 | // If no value declared, it's the default.
951 | group = x.flex || "0";
952 |
953 | if (x.match === kid && (!x[group] || (x[group] && parseInt(x[group], 10) <= 1))) {
954 | totalRatio += parseInt(group, 10);
955 |
956 | groups[group] = groups[group] || [];
957 | groups[group].push(x);
958 | }
959 | }
960 | }
961 |
962 | if (type && !kid.getAttribute(BoxOrdinalAttr)) {
963 | group = "1";
964 | kid.setAttribute(BoxOrdinalAttr, group);
965 |
966 | groups[group] = groups[group] || [];
967 | groups[group].push({
968 | match : kid
969 | });
970 | }
971 | }
972 |
973 | for (key in groups) {
974 | if (groups.hasOwnProperty(key)) {
975 | keys.push(key);
976 | }
977 | }
978 |
979 | keys.sort(function (a, b) {
980 | return b - a;
981 | });
982 |
983 | return {
984 | keys : keys,
985 | groups : groups,
986 | total : totalRatio
987 | };
988 | }
989 |
990 | function attachResizeListener(construct, params) {
991 | if (!RESIZE_LISTENER) {
992 | var storedWidth, storedHeight,
993 | currentWidth, currentHeight,
994 | docBody = doc.body,
995 | docEl = doc.documentElement,
996 | resizeTimer,
997 | innerWidth = "innerWidth", innerHeight = "innerHeight",
998 | clientWidth = "clientWidth", clientHeight = "clientHeight";
999 |
1000 | addEvent("resize", function () {
1001 | if (resizeTimer) {
1002 | window.clearTimeout(resizeTimer);
1003 | }
1004 |
1005 | resizeTimer = window.setTimeout(function () {
1006 | currentWidth = win[innerWidth] || docEl[innerWidth] || docEl[clientWidth] || docBody[clientWidth];
1007 | currentHeight = win[innerHeight] || docEl[innerHeight] || docEl[clientHeight] || docBody[clientHeight];
1008 |
1009 | if (storedWidth !== currentWidth || storedHeight !== currentHeight) {
1010 | FLX.updateInstance(NULL, NULL);
1011 |
1012 | storedWidth = currentWidth;
1013 | storedHeight = currentHeight;
1014 | }
1015 | }, 250);
1016 | });
1017 |
1018 | RESIZE_LISTENER = TRUE;
1019 | }
1020 | }
1021 |
1022 | function cleanPositioningProperties (children) {
1023 | var i, j, kid, w, h;
1024 |
1025 | for (i = 0, j = children.length; i < j; i++) {
1026 | kid = children[i];
1027 |
1028 | w = kid.style.width;
1029 | h = kid.style.height;
1030 |
1031 | kid.style.cssText = EMPTY_STRING;
1032 |
1033 | kid.style.width = w;
1034 | kid.style.height = h;
1035 | }
1036 | }
1037 |
1038 | function sanitizeChildren (target, nodes) {
1039 | var children = [], node, i, j;
1040 |
1041 | for (i = 0, j = nodes.length; i < j; i++) {
1042 | node = nodes[i];
1043 |
1044 | if (node) {
1045 | switch (node.nodeName.toLowerCase()) {
1046 | case "script" :
1047 | case "style" :
1048 | case "link" :
1049 | break;
1050 |
1051 | default :
1052 | if (node.nodeType === 1) {
1053 | children.push(node);
1054 | } else if ((node.nodeType === 3) && (node.isElementContentWhitespace || (ONLY_WHITESPACE).test(node.data))) {
1055 | target.removeChild(node);
1056 | i--;
1057 | }
1058 | break;
1059 | }
1060 | }
1061 | }
1062 |
1063 | return children;
1064 | }
1065 |
1066 | function parentFlex (target) {
1067 | var totalFlex = 0,
1068 | parent = target.parentNode,
1069 | obj,
1070 | matrix,
1071 | isNested;
1072 |
1073 | while (parent.FLX_DOM_ID) {
1074 | obj = FLEX_BOXES[parent.FLX_DOM_ID];
1075 | matrix = createMatchMatrix(obj.children, sanitizeChildren(parent, parent.childNodes), NULL);
1076 |
1077 | totalFlex += matrix.total;
1078 | isNested = TRUE;
1079 |
1080 | parent = parent.parentNode;
1081 | }
1082 |
1083 | return {
1084 | nested : isNested,
1085 | flex : totalFlex
1086 | };
1087 | }
1088 |
1089 | function dimensionValues (target, prop) {
1090 | var parent = target.parentNode,
1091 | obj, dimension, i, j, rule;
1092 |
1093 | if (parent.FLX_DOM_ID) {
1094 | obj = FLEX_BOXES[parent.FLX_DOM_ID];
1095 |
1096 | for (i = 0, j = obj.properties.length; i < j; i++) {
1097 | rule = obj.properties[i];
1098 |
1099 | if ((new RegExp(prop)).test(rule.property)) {
1100 | dimension = TRUE;
1101 | return FALSE;
1102 | }
1103 | }
1104 | }
1105 |
1106 | return dimension;
1107 | }
1108 |
1109 | function updateChildValues (params) {
1110 | var i, j, x;
1111 |
1112 | if (params.flexMatrix) {
1113 | for (i = 0, j = params.children.length; i < j; i++) {
1114 | x = params.children[i];
1115 | x.flex = params.flexMatrix[i];
1116 | }
1117 | }
1118 |
1119 | if (params.ordinalMatrix) {
1120 | for (i = 0, j = params.children.length; i < j; i++) {
1121 | x = params.children[i];
1122 | x["ordinal-group"] = params.ordinalMatrix[i];
1123 | }
1124 | }
1125 |
1126 | return params;
1127 | }
1128 |
1129 | function ensureStructuralIntegrity (params, instance) {
1130 | var target = params.target;
1131 |
1132 | if (!target.FLX_DOM_ID) {
1133 | target.FLX_DOM_ID = target.FLX_DOM_ID || (++FLX_DOM_ID);
1134 | }
1135 |
1136 | if (!params.nodes) {
1137 | params.nodes = sanitizeChildren(target, target.childNodes);
1138 | }
1139 |
1140 | if (!params.selector) {
1141 | params.selector = buildSelector(target);
1142 | target.setAttribute(FLX_PARENT_ATTR, TRUE);
1143 | }
1144 |
1145 | if (!params.properties) {
1146 | params.properties = [];
1147 | }
1148 |
1149 | if (!params.children) {
1150 | params.children = matchFlexChildren(target, LIBRARY, sanitizeChildren(target, target.childNodes));
1151 | }
1152 |
1153 | if (!params.nested) {
1154 | params.nested = params.selector + " [" + FLX_PARENT_ATTR + "]";
1155 | }
1156 |
1157 | params.target = target;
1158 | params._instance = instance;
1159 |
1160 | return params;
1161 | }
1162 |
1163 | selectivizrEngine = (function () {
1164 | var RE_COMMENT = /(\/\*[^*]*\*+([^\/][^*]*\*+)*\/)\s*?/g,
1165 | RE_IMPORT = /@import\s*(?:(?:(?:url\(\s*(['"]?)(.*)\1)\s*\))|(?:(['"])(.*)\3))\s*([^;]*);/g,
1166 | RE_ASSET_URL = /(behavior\s*?:\s*)?\burl\(\s*(["']?)(?!data:)([^"')]+)\2\s*\)/g,
1167 | RE_SELECTOR_GROUP = /((?:^|(?:\s*\})+)(?:\s*@media[^\{]+\{)?)\s*([^\{]*?[\[:][^{]+)/g,
1168 |
1169 | // Whitespace normalization regexp's
1170 | RE_TIDY_TRAILING_WHITESPACE = /([(\[+~])\s+/g,
1171 | RE_TIDY_LEADING_WHITESPACE = /\s+([)\]+~])/g,
1172 | RE_TIDY_CONSECUTIVE_WHITESPACE = /\s+/g,
1173 | RE_TIDY_TRIM_WHITESPACE = /^\s*((?:[\S\s]*\S)?)\s*$/;
1174 |
1175 | // --[ trim() ]---------------------------------------------------------
1176 | // removes leading, trailing whitespace from a string
1177 | function trim(text) {
1178 | return text.replace(RE_TIDY_TRIM_WHITESPACE, PLACEHOLDER_STRING);
1179 | }
1180 |
1181 | // --[ normalizeWhitespace() ]------------------------------------------
1182 | // removes leading, trailing and consecutive whitespace from a string
1183 | function normalizeWhitespace(text) {
1184 | return trim(text).replace(RE_TIDY_CONSECUTIVE_WHITESPACE, SPACE_STRING);
1185 | }
1186 |
1187 | // --[ normalizeSelectorWhitespace() ]----------------------------------
1188 | // tidys whitespace around selector brackets and combinators
1189 | function normalizeSelectorWhitespace(selectorText) {
1190 | return normalizeWhitespace(selectorText.replace(RE_TIDY_TRAILING_WHITESPACE, PLACEHOLDER_STRING).replace(RE_TIDY_LEADING_WHITESPACE, PLACEHOLDER_STRING));
1191 | }
1192 |
1193 | // --[ patchStyleSheet() ]----------------------------------------------
1194 | // Scans the passed cssText for selectors that require emulation and
1195 | // creates one or more patches for each matched selector.
1196 | function patchStyleSheet(cssText) {
1197 | return cssText.replace(RE_SELECTOR_GROUP, function (m, prefix, selectorText) {
1198 | var selectorGroups, selector,
1199 | i, j, group;
1200 |
1201 | selectorGroups = selectorText.split(",");
1202 |
1203 | for (i = 0, j = selectorGroups.length; i < j; i++) {
1204 | group = selectorGroups[i];
1205 | selector = normalizeSelectorWhitespace(group) + SPACE_STRING;
1206 | }
1207 |
1208 | return prefix + selectorGroups.join(",");
1209 | });
1210 | }
1211 |
1212 | // --[ getXHRObject() ]-------------------------------------------------
1213 | function getXHRObject() {
1214 | if (win.XMLHttpRequest) {
1215 | return new win.XMLHttpRequest();
1216 | }
1217 |
1218 | try {
1219 | return new win.ActiveXObject("Microsoft.XMLHTTP");
1220 | } catch (e) {
1221 | return NULL;
1222 | }
1223 | }
1224 |
1225 | function parseInlineStyles ( text ) {
1226 | var reg = /