jekyll-theme-prettydocs 0.0.6 → 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (195) hide show
  1. checksums.yaml +5 -5
  2. data/LICENSE.txt +0 -0
  3. data/README.md +59 -178
  4. data/_includes/footer.html +6 -6
  5. data/_includes/home.html +122 -0
  6. data/_includes/promo-block.html +29 -86
  7. data/_layouts/home.html +36 -53
  8. data/_layouts/page.html +51 -5
  9. data/assets/.DS_Store +0 -0
  10. data/assets/css/.DS_Store +0 -0
  11. data/assets/css/styles.css +1373 -1267
  12. data/assets/images/.DS_Store +0 -0
  13. data/assets/images/demo/.DS_Store +0 -0
  14. data/assets/images/demo/fontawesome-icons.png +0 -0
  15. data/assets/images/demo/instance-promo.jpg +0 -0
  16. data/assets/images/demo/theme-atom.png +0 -0
  17. data/assets/images/demo/theme-decibel.png +0 -0
  18. data/assets/images/demo/theme-delta.png +0 -0
  19. data/assets/images/demo/theme-devstudio.png +0 -0
  20. data/assets/images/demo/theme-instance.png +0 -0
  21. data/assets/images/demo/theme-onboard.png +0 -0
  22. data/assets/images/demo/theme-orbit.png +0 -0
  23. data/assets/images/demo/theme-pillar.png +0 -0
  24. data/assets/images/demo/theme-sphere.png +0 -0
  25. data/assets/images/demo/theme-startupkit.png +0 -0
  26. data/assets/images/demo/theme-tempo.png +0 -0
  27. data/assets/images/demo/theme-trades.png +0 -0
  28. data/assets/images/empty.gif +0 -0
  29. data/assets/images/untitled folder/.DS_Store +0 -0
  30. data/assets/images/untitled folder/bootstrap-template-for-schools-academy.png +0 -0
  31. data/assets/images/untitled folder/crowdfunding-landing-page-onboard.png +0 -0
  32. data/assets/images/untitled folder/free-bootstrap-portfolio-theme-for-developers.png +0 -0
  33. data/assets/images/untitled folder/free-bootstrap-theme-appkit-landing.png +0 -0
  34. data/assets/images/untitled folder/free-bootstrap-theme-for-developers-devaid.png +0 -0
  35. data/assets/images/untitled folder/free-bootstrap-theme-for-develpers-prettydocs.png +0 -0
  36. data/assets/images/untitled folder/free-bootstrap-theme-for-documentation-prettydedocs.png +0 -0
  37. data/assets/images/untitled folder/free-bootstrap-theme-for-startups-developers-appkit-landing.png +0 -0
  38. data/assets/images/untitled folder/html5-website-template-college-green.png +0 -0
  39. data/assets/images/untitled folder/html5-website-template-placeholder.png +0 -0
  40. data/assets/images/untitled folder/restaurant-landing-page-epicure.png +0 -0
  41. data/assets/images/untitled folder/wedding-invitation-landing-page-matrimony.png +0 -0
  42. data/assets/js/.DS_Store +0 -0
  43. data/assets/js/main.js +42 -46
  44. data/assets/plugins/.DS_Store +0 -0
  45. data/assets/plugins/bootstrap/css/bootstrap-grid.css +1912 -0
  46. data/assets/plugins/bootstrap/css/bootstrap-grid.css.map +0 -0
  47. data/assets/plugins/bootstrap/css/bootstrap-grid.min.css +7 -0
  48. data/assets/plugins/bootstrap/css/bootstrap-grid.min.css.map +0 -0
  49. data/assets/plugins/bootstrap/css/bootstrap-reboot.css +331 -0
  50. data/assets/plugins/bootstrap/css/bootstrap-reboot.css.map +0 -0
  51. data/assets/plugins/bootstrap/css/bootstrap-reboot.min.css +8 -0
  52. data/assets/plugins/bootstrap/css/bootstrap-reboot.min.css.map +0 -0
  53. data/assets/plugins/bootstrap/css/bootstrap.css +7946 -5683
  54. data/assets/plugins/bootstrap/css/bootstrap.css.map +0 -0
  55. data/assets/plugins/bootstrap/css/bootstrap.min.css +4 -3
  56. data/assets/plugins/bootstrap/css/bootstrap.min.css.map +0 -0
  57. data/assets/plugins/bootstrap/js/bootstrap.bundle.js +6461 -0
  58. data/assets/plugins/bootstrap/js/bootstrap.bundle.js.map +0 -0
  59. data/assets/plugins/bootstrap/js/bootstrap.bundle.min.js +7 -0
  60. data/assets/plugins/bootstrap/js/bootstrap.bundle.min.js.map +0 -0
  61. data/assets/plugins/bootstrap/js/bootstrap.js +3448 -1867
  62. data/assets/plugins/bootstrap/js/bootstrap.js.map +0 -0
  63. data/assets/plugins/bootstrap/js/bootstrap.min.js +6 -6
  64. data/assets/plugins/bootstrap/js/bootstrap.min.js.map +0 -0
  65. data/assets/plugins/jquery-3.3.1.min.js +2 -0
  66. data/assets/plugins/lightbox/Gruntfile.js +84 -83
  67. data/assets/plugins/lightbox/ISSUE_TEMPLATE.md +9 -0
  68. data/assets/plugins/lightbox/LICENSE +21 -0
  69. data/assets/plugins/lightbox/README.md +15 -10
  70. data/assets/plugins/lightbox/bower.json +29 -38
  71. data/assets/plugins/lightbox/dist/ekko-lightbox.css +2 -62
  72. data/assets/plugins/lightbox/dist/ekko-lightbox.js +668 -400
  73. data/assets/plugins/lightbox/dist/ekko-lightbox.js.map +1 -0
  74. data/assets/plugins/lightbox/dist/ekko-lightbox.min.js +2 -7
  75. data/assets/plugins/lightbox/dist/ekko-lightbox.min.js.map +1 -0
  76. data/assets/plugins/lightbox/ekko-lightbox.js +671 -0
  77. data/assets/plugins/lightbox/ekko-lightbox.less +139 -64
  78. data/assets/plugins/lightbox/examples/bs3.html +596 -0
  79. data/assets/plugins/lightbox/index.html +659 -0
  80. data/assets/plugins/lightbox/package.json +57 -46
  81. data/assets/plugins/lightbox/webpack.config.js +89 -0
  82. data/assets/plugins/lightbox/yarn.lock +6683 -0
  83. data/assets/plugins/prism/min/prism-min.js +0 -0
  84. data/assets/plugins/stickyfill/.editorconfig +9 -0
  85. data/assets/plugins/stickyfill/.gitignore +1 -0
  86. data/assets/plugins/stickyfill/Gruntfile.js +106 -0
  87. data/assets/plugins/stickyfill/LICENSE +21 -0
  88. data/assets/plugins/stickyfill/README.md +229 -0
  89. data/assets/plugins/stickyfill/dist/stickyfill.es6.js +507 -0
  90. data/assets/plugins/stickyfill/dist/stickyfill.js +520 -0
  91. data/assets/plugins/stickyfill/dist/stickyfill.min.js +7 -0
  92. data/assets/plugins/stickyfill/package-lock.json +2109 -0
  93. data/assets/plugins/stickyfill/package.json +32 -0
  94. data/assets/plugins/stickyfill/src/stickyfill.js +500 -0
  95. data/assets/plugins/stickyfill/test/index.html +941 -0
  96. data/assets/plugins/stickyfill/test/js/jquery-3.1.1.min.js +4 -0
  97. data/assets/plugins/stickyfill/types/index.d.ts +17 -0
  98. data/assets/plugins/stickyfill/yarn.lock +1475 -0
  99. data/assets/scss/.DS_Store +0 -0
  100. data/assets/{less/base.less → scss/_base.scss} +283 -307
  101. data/assets/{less/doc.less → scss/_doc.scss} +747 -747
  102. data/assets/{less/landing.less → scss/_landing.scss} +231 -244
  103. data/assets/scss/_mixins.scss +175 -0
  104. data/assets/scss/config.codekit3 +2243 -0
  105. data/assets/scss/styles.scss +45 -0
  106. metadata +76 -96
  107. data/_includes/blue-doc-wrapper.html +0 -293
  108. data/_includes/blue-header.html +0 -17
  109. data/_includes/card-charts.html +0 -10
  110. data/_includes/card-components.html +0 -10
  111. data/_includes/card-faqs.html +0 -10
  112. data/_includes/card-license.html +0 -10
  113. data/_includes/card-quick.html +0 -10
  114. data/_includes/card-showcase.html +0 -10
  115. data/_includes/cards-section.html +0 -47
  116. data/_includes/doc-wrapper.html +0 -170
  117. data/_includes/fb-root.html +0 -9
  118. data/_includes/green-doc-wrapper.html +0 -484
  119. data/_includes/green-header.html +0 -17
  120. data/_includes/header-home.html +0 -21
  121. data/_includes/header.html +0 -70
  122. data/_includes/icon-github.html +0 -1
  123. data/_includes/landing-header.html +0 -22
  124. data/_includes/orange-doc-wrapper.html +0 -65
  125. data/_includes/orange-header.html +0 -17
  126. data/_includes/pink-doc-wrapper.html +0 -281
  127. data/_includes/pink-header.html +0 -17
  128. data/_includes/purple-doc-wrapper.html +0 -138
  129. data/_includes/purple-header.html +0 -17
  130. data/_layouts/blue.html +0 -53
  131. data/_layouts/default.html +0 -53
  132. data/_layouts/green.html +0 -53
  133. data/_layouts/orange.html +0 -53
  134. data/_layouts/pink.html +0 -53
  135. data/_layouts/post.html +0 -5
  136. data/_layouts/purple.html +0 -53
  137. data/assets/images/demo/a-complete-example-of-page.png +0 -0
  138. data/assets/less/mixins.less +0 -185
  139. data/assets/less/styles.less +0 -13
  140. data/assets/less/theme-default.less +0 -115
  141. data/assets/plugins/bootstrap/css/bootstrap-theme.css +0 -587
  142. data/assets/plugins/bootstrap/css/bootstrap-theme.css.map +0 -0
  143. data/assets/plugins/bootstrap/css/bootstrap-theme.min.css +0 -6
  144. data/assets/plugins/bootstrap/css/bootstrap-theme.min.css.map +0 -0
  145. data/assets/plugins/bootstrap/fonts/glyphicons-halflings-regular.eot +0 -0
  146. data/assets/plugins/bootstrap/fonts/glyphicons-halflings-regular.svg +0 -288
  147. data/assets/plugins/bootstrap/fonts/glyphicons-halflings-regular.ttf +0 -0
  148. data/assets/plugins/bootstrap/fonts/glyphicons-halflings-regular.woff +0 -0
  149. data/assets/plugins/bootstrap/fonts/glyphicons-halflings-regular.woff2 +0 -0
  150. data/assets/plugins/bootstrap/js/npm.js +0 -13
  151. data/assets/plugins/font-awesome/HELP-US-OUT.txt +0 -7
  152. data/assets/plugins/font-awesome/css/font-awesome.css +0 -2199
  153. data/assets/plugins/font-awesome/css/font-awesome.min.css +0 -4
  154. data/assets/plugins/font-awesome/fonts/FontAwesome.otf +0 -0
  155. data/assets/plugins/font-awesome/fonts/fontawesome-webfont.eot +0 -0
  156. data/assets/plugins/font-awesome/fonts/fontawesome-webfont.svg +0 -685
  157. data/assets/plugins/font-awesome/fonts/fontawesome-webfont.ttf +0 -0
  158. data/assets/plugins/font-awesome/fonts/fontawesome-webfont.woff +0 -0
  159. data/assets/plugins/font-awesome/fonts/fontawesome-webfont.woff2 +0 -0
  160. data/assets/plugins/font-awesome/less/animated.less +0 -34
  161. data/assets/plugins/font-awesome/less/bordered-pulled.less +0 -25
  162. data/assets/plugins/font-awesome/less/core.less +0 -12
  163. data/assets/plugins/font-awesome/less/fixed-width.less +0 -6
  164. data/assets/plugins/font-awesome/less/font-awesome.less +0 -18
  165. data/assets/plugins/font-awesome/less/icons.less +0 -733
  166. data/assets/plugins/font-awesome/less/larger.less +0 -13
  167. data/assets/plugins/font-awesome/less/list.less +0 -19
  168. data/assets/plugins/font-awesome/less/mixins.less +0 -60
  169. data/assets/plugins/font-awesome/less/path.less +0 -15
  170. data/assets/plugins/font-awesome/less/rotated-flipped.less +0 -20
  171. data/assets/plugins/font-awesome/less/screen-reader.less +0 -5
  172. data/assets/plugins/font-awesome/less/stacked.less +0 -20
  173. data/assets/plugins/font-awesome/less/variables.less +0 -744
  174. data/assets/plugins/font-awesome/scss/_animated.scss +0 -34
  175. data/assets/plugins/font-awesome/scss/_bordered-pulled.scss +0 -25
  176. data/assets/plugins/font-awesome/scss/_core.scss +0 -12
  177. data/assets/plugins/font-awesome/scss/_fixed-width.scss +0 -6
  178. data/assets/plugins/font-awesome/scss/_icons.scss +0 -733
  179. data/assets/plugins/font-awesome/scss/_larger.scss +0 -13
  180. data/assets/plugins/font-awesome/scss/_list.scss +0 -19
  181. data/assets/plugins/font-awesome/scss/_mixins.scss +0 -60
  182. data/assets/plugins/font-awesome/scss/_path.scss +0 -15
  183. data/assets/plugins/font-awesome/scss/_rotated-flipped.scss +0 -20
  184. data/assets/plugins/font-awesome/scss/_screen-reader.scss +0 -5
  185. data/assets/plugins/font-awesome/scss/_stacked.scss +0 -20
  186. data/assets/plugins/font-awesome/scss/_variables.scss +0 -744
  187. data/assets/plugins/font-awesome/scss/font-awesome.scss +0 -18
  188. data/assets/plugins/jquery-1.12.3.min.js +0 -5
  189. data/assets/plugins/lightbox/LICENSE.txt +0 -339
  190. data/assets/plugins/lightbox/dist/ekko-lightbox.min.css +0 -6
  191. data/assets/plugins/lightbox/ekko-lightbox.coffee +0 -353
  192. data/assets/plugins/lightbox/examples/index.html +0 -559
  193. data/assets/plugins/lightbox/examples/remote/page1.html +0 -9
  194. data/assets/plugins/lightbox/examples/remote/page2.html +0 -9
  195. data/assets/plugins/lightbox/examples/remote/readme.md +0 -1
File without changes
@@ -0,0 +1,9 @@
1
+ # top-most EditorConfig file
2
+ root = true
3
+
4
+ # Unix-style newlines with a newline ending every file
5
+ [*]
6
+ end_of_line = lf
7
+ insert_final_newline = true
8
+ indent_style = space
9
+ indent_size = 4
@@ -0,0 +1 @@
1
+ node_modules
@@ -0,0 +1,106 @@
1
+ module.exports = function(grunt) {
2
+ 'use strict';
3
+
4
+ grunt.initConfig({
5
+ pkg: grunt.file.readJSON('package.json'),
6
+ banner:
7
+ `/*!
8
+ * Stickyfill – \`position: sticky\` polyfill
9
+ * v. <%= pkg.version %> | <%= pkg.homepage %>
10
+ * MIT License
11
+ */
12
+ `,
13
+
14
+ babel: {
15
+ options: {
16
+ presets: ['es2015']
17
+ },
18
+ dist: {
19
+ files: {
20
+ 'dist/stickyfill.js': 'src/stickyfill.js'
21
+ }
22
+ }
23
+ },
24
+
25
+ wrap: {
26
+ es5: {
27
+ options: {
28
+ wrapper: [
29
+ '<%= banner %>\n;(function(window, document) {',
30
+ '})(window, document);'
31
+ ],
32
+ indent: ' '
33
+ },
34
+ files: {
35
+ 'dist/stickyfill.js': ['dist/stickyfill.js']
36
+ }
37
+ },
38
+ es6: {
39
+ options: {
40
+ wrapper: [
41
+ '<%= banner %>',
42
+ ''
43
+ ]
44
+ },
45
+ files: {
46
+ 'dist/stickyfill.es6.js': ['src/stickyfill.js']
47
+ }
48
+ }
49
+ },
50
+
51
+ uglify: {
52
+ options: {
53
+ banner: '<%= banner %>',
54
+ mangle: true
55
+ },
56
+ dist: {
57
+ files: {
58
+ 'dist/stickyfill.min.js': ['dist/stickyfill.js']
59
+ }
60
+ }
61
+ },
62
+
63
+ bump: {
64
+ options: {
65
+ files: ['package.json'],
66
+ updateConfigs: ['pkg'],
67
+ commit: true,
68
+ commitMessage: 'v %VERSION%',
69
+ commitFiles: ['.'],
70
+ createTag: true,
71
+ tagName: '%VERSION%',
72
+ tagMessage: 'v %VERSION%',
73
+ push: false
74
+ }
75
+ },
76
+
77
+ shell: {
78
+ push: {
79
+ command: 'git push'
80
+ },
81
+
82
+ pushTags: {
83
+ command: 'git push --tags'
84
+ },
85
+
86
+ publishToNpm: {
87
+ command: 'npm publish'
88
+ }
89
+ },
90
+
91
+ watch: {
92
+ files: ['src/**/*.js'],
93
+ tasks: ['build']
94
+ }
95
+ });
96
+
97
+ grunt.loadNpmTasks('grunt-wrap');
98
+ grunt.loadNpmTasks('grunt-babel');
99
+ grunt.loadNpmTasks('grunt-contrib-uglify');
100
+ grunt.loadNpmTasks('grunt-contrib-watch');
101
+ grunt.loadNpmTasks('grunt-bump');
102
+ grunt.loadNpmTasks('grunt-shell');
103
+ grunt.registerTask('build', ['babel', 'wrap', 'uglify']);
104
+ grunt.registerTask('release', ['bump-only:patch', 'build', 'bump-commit', 'shell:push', 'shell:pushTags', 'shell:publishToNpm']);
105
+ grunt.registerTask('default', ['build', 'watch']);
106
+ };
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2017 Oleg Korsunsky
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,229 @@
1
+ # Polyfill for CSS `position: sticky`
2
+
3
+ The most accurate sticky polyfill out in the wild.
4
+
5
+ Check out [the demo](http://wd.dizaina.net/en/scripts/stickyfill/) and [use cases test page](http://wilddeer.github.io/stickyfill/test/).
6
+
7
+ ## What it does
8
+
9
+ - supports top-positioned stickies,
10
+ - works in IE9+,
11
+ - disables itself in older IEs and in browsers with native `position: sticky` support,
12
+ - mimics original `position: sticky` behavior:
13
+
14
+ - uses parent node as a boundary box,
15
+ - behaves nicely with horizontal page scrolling,
16
+ - only works on elements with specified `top`,
17
+ - mimics native `top` and `margin-bottom` behavior,
18
+ - ~~works with table cells~~ removed for consistency until Firefox [makes a native implementation](https://bugzilla.mozilla.org/show_bug.cgi?id=975644)
19
+
20
+ ## What it doesn't
21
+
22
+ - doesn't support left, right, bottom or combined stickies,
23
+ - doesn't work in overflowed blocks,
24
+ - doesn't parse your CSS! Launch it manually.
25
+
26
+ ## Installation
27
+
28
+ ### NPM
29
+
30
+ ```
31
+ npm install stickyfilljs --save
32
+ ```
33
+
34
+ ### Yarn
35
+
36
+ ```
37
+ yarn add stickyfilljs
38
+ ```
39
+
40
+ ### Raw ES6 module
41
+
42
+ [stickyfill.es6.js](https://raw.github.com/wilddeer/stickyfill/master/dist/stickyfill.es6.js)
43
+
44
+ ### Old fashioned
45
+
46
+ Download minified production ES5 script:
47
+
48
+ [stickyfill.min.js](https://raw.github.com/wilddeer/stickyfill/master/dist/stickyfill.min.js)
49
+
50
+ Include it on your page:
51
+
52
+ ```html
53
+ <script src="path/to/stickyfill.min.js"></script>
54
+ ```
55
+
56
+ ## Usage
57
+
58
+ First things first, make sure your stickies work in the [browsers that support them natively](http://caniuse.com/#feat=css-sticky), e.g.:
59
+
60
+ ```html
61
+ <div class="sticky">
62
+ ...
63
+ </div>
64
+ ```
65
+
66
+ ```css
67
+ .sticky {
68
+ position: -webkit-sticky;
69
+ position: sticky;
70
+ top: 0;
71
+ }
72
+ ```
73
+
74
+ Then apply the polyfill:
75
+
76
+ JS:
77
+
78
+ ```js
79
+ var elements = document.querySelectorAll('.sticky');
80
+ Stickyfill.add(elements);
81
+ ```
82
+
83
+ or JS + jQuery:
84
+
85
+ ```js
86
+ var elements = $('.sticky');
87
+ Stickyfill.add(elements);
88
+ ```
89
+
90
+ Also worth having a clearfix:
91
+
92
+ ```css
93
+ .sticky:before,
94
+ .sticky:after {
95
+ content: '';
96
+ display: table;
97
+ }
98
+ ```
99
+
100
+ ## Pro tips
101
+
102
+ - `top` specifies sticky’s position relatively to the top edge of the viewport. It accepts negative values, too.
103
+ - You can push sticky’s bottom limit up or down by specifying positive or negative `margin-bottom`.
104
+ - Any non-default value (not `visible`) for `overflow`, `overflow-x`, or `overflow-y` on any of the ancestor elements anchors the sticky to the overflow context of that ancestor. Simply put, scrolling the ancestor will cause the sticky to stick, scrolling the window will not. This is expected with `overflow: auto` and `overflow: scroll`, but often causes confusion with `overflow: hidden`. Keep this in mind, folks!
105
+
106
+ Check out [the test page](http://wilddeer.github.io/stickyfill/test/) to understand stickies better.
107
+
108
+ ## API
109
+
110
+ ### `Stickyfill`
111
+
112
+ #### `Stickyfill.addOne(element)`
113
+
114
+ `element` – `HTMLElement` or iterable element list ([`NodeList`](https://developer.mozilla.org/en/docs/Web/API/NodeList), jQuery collection, etc.). First element of the list is used.
115
+
116
+ Adds the element as a sticky. Returns new [Sticky](#stickyfillsticky) instance associated with the element.
117
+
118
+ If there’s a sticky associated with the element, returns existing [Sticky](#stickyfillsticky) instance instead.
119
+
120
+ #### `Stickyfill.add(elementList)`
121
+
122
+ `elementList` – iterable element list ([`NodeList`](https://developer.mozilla.org/en/docs/Web/API/NodeList), jQuery collection, etc.) or single `HTMLElement`.
123
+
124
+ Adds the elements as stickies. Skips the elements that have stickies associated with them.
125
+
126
+ Returns an array of [Sticky](#stickyfillsticky) instances associated with the elements (both existing and new ones).
127
+
128
+ #### `Stickyfill.refreshAll()`
129
+
130
+ Refreshes all existing stickies, updates their parameters and positions.
131
+
132
+ All stickies are automatically refreshed after window resizes and device orientations changes.
133
+
134
+ There’s also a fast but not very accurate layout change detection that triggers this method. Call this method manually in case automatic detection fails.
135
+
136
+ #### `Stickyfill.removeOne(element)`
137
+
138
+ `element` – `HTMLElement` or iterable element list ([`NodeList`](https://developer.mozilla.org/en/docs/Web/API/NodeList), jQuery collection, etc.). First element of the list is used.
139
+
140
+ Removes sticky associated with the element.
141
+
142
+ #### `Stickyfill.remove(elementList)`
143
+
144
+ `elementList` – iterable element list ([`NodeList`](https://developer.mozilla.org/en/docs/Web/API/NodeList), jQuery collection, etc.) or single `HTMLElement`.
145
+
146
+ Removes stickies associated with the elements in the list.
147
+
148
+ #### `Stickyfill.removeAll()`
149
+
150
+ Removes all existing stickies.
151
+
152
+ #### `Stickyfill.stickies`
153
+
154
+ Array of existing [Sticky](#Stickyfill.Sticky) instances.
155
+
156
+ ### `Stickyfill.Sticky`
157
+
158
+ Sticky class. You can use it directly if you want:
159
+
160
+ ```js
161
+ const sticky = new Stickyfill.Sticky(element);
162
+ ```
163
+
164
+ Throws an error if there’s a sticky already bound to the element.
165
+
166
+ #### `Sticky.refresh()`
167
+
168
+ Refreshes the sticky, updates its parameters and position.
169
+
170
+ #### `Sticky.remove()`
171
+
172
+ Removes the sticky. Restores the element to its original state.
173
+
174
+ ## Feature requests
175
+
176
+ ### TL;DR
177
+
178
+ These features will never be implemented in Stickyfill:
179
+
180
+ - Callbacks for sticky state changes
181
+ - Switching classes between different sticky states
182
+ - Other features that add non-standard functionality
183
+
184
+ If your request isn’t about one of these, you are welcome to [create an issue](https://github.com/wilddeer/stickyfill/issues/new). Please check [existing issues](https://github.com/wilddeer/stickyfill/issues) before creating new one.
185
+
186
+ ### Some reasoning
187
+
188
+ Stickyfill is a [polyfill](https://en.wikipedia.org/wiki/Polyfill). This means that it implements a feature (sticky positioning in this case) that already exists in some browsers natively, and allows to use this feature in the browsers that don’t support it yet and older versions of the browsers that didn’t support it at the time. This is its only purpose.
189
+
190
+ This also means that Stickyfill does nothing in the browsers that _do_ support sticky positioning. Which, in turn, means that those browsers won’t support any additional non-standard features.
191
+
192
+ ## Bug reports
193
+
194
+ Check [existing issues](https://github.com/wilddeer/stickyfill/issues) before creating new one. **Please provide a live reproduction of a bug.**
195
+
196
+ ## Contributing
197
+
198
+ ### Prerequisites
199
+
200
+ - Install Git 😱
201
+ - Install [node](https://nodejs.org/en/)
202
+ - Install [grunt-cli](http://gruntjs.com/getting-started#installing-the-cli)
203
+ - Clone the repo, `cd` into the repo folder, run `npm install` (or `yarn` if you are fancy).
204
+
205
+ Ok, you are all set.
206
+
207
+ ### Building and testing
208
+
209
+ `cd` into the repo folder and run `grunt`. It will build the project from `/src/strickyfill.js` into `/dist` and run the watcher that will rebuild the project every time you change something in the source file.
210
+
211
+ Make changes to the source file. Stick to ES6 syntax.
212
+
213
+ Open `/test/index.html` in a browser that [doesn’t support](http://caniuse.com/#feat=css-sticky) `position: sticky` to check that everything works as expected. Compare the results to the same page in a browser that supports `position: sticky`.
214
+
215
+ Commit the changes. **DO NOT** commit the files in the `/dist` folder. **DO NOT** change the version in `package.json`.
216
+
217
+ Make a pull request 👍
218
+
219
+ ### Adding / removing / updating npm packages
220
+
221
+ Use [Yarn](https://yarnpkg.com/), dont’t forget to commit `yarn.lock`.
222
+
223
+ ## Using Stickyfill?
224
+
225
+ 🍻 [Buy me a beer](https://www.paypal.me/wilddeer/0usd)
226
+
227
+ ## License
228
+
229
+ [MIT license](LICENSE).
@@ -0,0 +1,507 @@
1
+ /*!
2
+ * Stickyfill – `position: sticky` polyfill
3
+ * v. 2.0.5 | https://github.com/wilddeer/stickyfill
4
+ * MIT License
5
+ */
6
+
7
+ 'use strict';
8
+
9
+ /*
10
+ * 1. Check if the browser supports `position: sticky` natively or is too old to run the polyfill.
11
+ * If either of these is the case set `seppuku` flag. It will be checked later to disable key features
12
+ * of the polyfill, but the API will remain functional to avoid breaking things.
13
+ */
14
+ let seppuku = false;
15
+
16
+ // The polyfill cant’t function properly without `getComputedStyle`.
17
+ if (!window.getComputedStyle) seppuku = true;
18
+ // Dont’t get in a way if the browser supports `position: sticky` natively.
19
+ else {
20
+ const testNode = document.createElement('div');
21
+
22
+ if (
23
+ ['', '-webkit-', '-moz-', '-ms-'].some(prefix => {
24
+ try {
25
+ testNode.style.position = prefix + 'sticky';
26
+ }
27
+ catch(e) {}
28
+
29
+ return testNode.style.position != '';
30
+ })
31
+ ) seppuku = true;
32
+ }
33
+
34
+
35
+ /*
36
+ * 2. “Global” vars used across the polyfill
37
+ */
38
+
39
+ // Check if Shadow Root constructor exists to make further checks simpler
40
+ const shadowRootExists = typeof ShadowRoot !== 'undefined';
41
+
42
+ // Last saved scroll position
43
+ const scroll = {
44
+ top: null,
45
+ left: null
46
+ };
47
+
48
+ // Array of created Sticky instances
49
+ const stickies = [];
50
+
51
+
52
+ /*
53
+ * 3. Utility functions
54
+ */
55
+ function extend (targetObj, sourceObject) {
56
+ for (var key in sourceObject) {
57
+ if (sourceObject.hasOwnProperty(key)) {
58
+ targetObj[key] = sourceObject[key];
59
+ }
60
+ }
61
+ }
62
+
63
+ function parseNumeric (val) {
64
+ return parseFloat(val) || 0;
65
+ }
66
+
67
+ function getDocOffsetTop (node) {
68
+ let docOffsetTop = 0;
69
+
70
+ while (node) {
71
+ docOffsetTop += node.offsetTop;
72
+ node = node.offsetParent;
73
+ }
74
+
75
+ return docOffsetTop;
76
+ }
77
+
78
+
79
+ /*
80
+ * 4. Sticky class
81
+ */
82
+ class Sticky {
83
+ constructor (node) {
84
+ if (!(node instanceof HTMLElement))
85
+ throw new Error('First argument must be HTMLElement');
86
+ if (stickies.some(sticky => sticky._node === node))
87
+ throw new Error('Stickyfill is already applied to this node');
88
+
89
+ this._node = node;
90
+ this._stickyMode = null;
91
+ this._active = false;
92
+
93
+ stickies.push(this);
94
+
95
+ this.refresh();
96
+ }
97
+
98
+ refresh () {
99
+ if (seppuku || this._removed) return;
100
+ if (this._active) this._deactivate();
101
+
102
+ const node = this._node;
103
+
104
+ /*
105
+ * 1. Save node computed props
106
+ */
107
+ const nodeComputedStyle = getComputedStyle(node);
108
+ const nodeComputedProps = {
109
+ top: nodeComputedStyle.top,
110
+ display: nodeComputedStyle.display,
111
+ marginTop: nodeComputedStyle.marginTop,
112
+ marginBottom: nodeComputedStyle.marginBottom,
113
+ marginLeft: nodeComputedStyle.marginLeft,
114
+ marginRight: nodeComputedStyle.marginRight,
115
+ cssFloat: nodeComputedStyle.cssFloat
116
+ };
117
+
118
+ /*
119
+ * 2. Check if the node can be activated
120
+ */
121
+ if (
122
+ isNaN(parseFloat(nodeComputedProps.top)) ||
123
+ nodeComputedProps.display == 'table-cell' ||
124
+ nodeComputedProps.display == 'none'
125
+ ) return;
126
+
127
+ this._active = true;
128
+
129
+ /*
130
+ * 3. Get necessary node parameters
131
+ */
132
+ const referenceNode = node.parentNode;
133
+ const parentNode = shadowRootExists && referenceNode instanceof ShadowRoot? referenceNode.host: referenceNode;
134
+ const nodeWinOffset = node.getBoundingClientRect();
135
+ const parentWinOffset = parentNode.getBoundingClientRect();
136
+ const parentComputedStyle = getComputedStyle(parentNode);
137
+
138
+ this._parent = {
139
+ node: parentNode,
140
+ styles: {
141
+ position: parentNode.style.position
142
+ },
143
+ offsetHeight: parentNode.offsetHeight
144
+ };
145
+ this._offsetToWindow = {
146
+ left: nodeWinOffset.left,
147
+ right: document.documentElement.clientWidth - nodeWinOffset.right
148
+ };
149
+ this._offsetToParent = {
150
+ top: nodeWinOffset.top - parentWinOffset.top - parseNumeric(parentComputedStyle.borderTopWidth),
151
+ left: nodeWinOffset.left - parentWinOffset.left - parseNumeric(parentComputedStyle.borderLeftWidth),
152
+ right: -nodeWinOffset.right + parentWinOffset.right - parseNumeric(parentComputedStyle.borderRightWidth)
153
+ };
154
+ this._styles = {
155
+ position: node.style.position,
156
+ top: node.style.top,
157
+ bottom: node.style.bottom,
158
+ left: node.style.left,
159
+ right: node.style.right,
160
+ width: node.style.width,
161
+ marginTop: node.style.marginTop,
162
+ marginLeft: node.style.marginLeft,
163
+ marginRight: node.style.marginRight
164
+ };
165
+
166
+ const nodeTopValue = parseNumeric(nodeComputedProps.top);
167
+ this._limits = {
168
+ start: nodeWinOffset.top + window.pageYOffset - nodeTopValue,
169
+ end: parentWinOffset.top + window.pageYOffset + parentNode.offsetHeight -
170
+ parseNumeric(parentComputedStyle.borderBottomWidth) - node.offsetHeight -
171
+ nodeTopValue - parseNumeric(nodeComputedProps.marginBottom)
172
+ };
173
+
174
+ /*
175
+ * 4. Ensure that the node will be positioned relatively to the parent node
176
+ */
177
+ const parentPosition = parentComputedStyle.position;
178
+
179
+ if (
180
+ parentPosition != 'absolute' &&
181
+ parentPosition != 'relative'
182
+ ) {
183
+ parentNode.style.position = 'relative';
184
+ }
185
+
186
+ /*
187
+ * 5. Recalc node position.
188
+ * It’s important to do this before clone injection to avoid scrolling bug in Chrome.
189
+ */
190
+ this._recalcPosition();
191
+
192
+ /*
193
+ * 6. Create a clone
194
+ */
195
+ const clone = this._clone = {};
196
+ clone.node = document.createElement('div');
197
+
198
+ // Apply styles to the clone
199
+ extend(clone.node.style, {
200
+ width: nodeWinOffset.right - nodeWinOffset.left + 'px',
201
+ height: nodeWinOffset.bottom - nodeWinOffset.top + 'px',
202
+ marginTop: nodeComputedProps.marginTop,
203
+ marginBottom: nodeComputedProps.marginBottom,
204
+ marginLeft: nodeComputedProps.marginLeft,
205
+ marginRight: nodeComputedProps.marginRight,
206
+ cssFloat: nodeComputedProps.cssFloat,
207
+ padding: 0,
208
+ border: 0,
209
+ borderSpacing: 0,
210
+ fontSize: '1em',
211
+ position: 'static'
212
+ });
213
+
214
+ referenceNode.insertBefore(clone.node, node);
215
+ clone.docOffsetTop = getDocOffsetTop(clone.node);
216
+ }
217
+
218
+ _recalcPosition () {
219
+ if (!this._active || this._removed) return;
220
+
221
+ const stickyMode = scroll.top <= this._limits.start? 'start': scroll.top >= this._limits.end? 'end': 'middle';
222
+
223
+ if (this._stickyMode == stickyMode) return;
224
+
225
+ switch (stickyMode) {
226
+ case 'start':
227
+ extend(this._node.style, {
228
+ position: 'absolute',
229
+ left: this._offsetToParent.left + 'px',
230
+ right: this._offsetToParent.right + 'px',
231
+ top: this._offsetToParent.top + 'px',
232
+ bottom: 'auto',
233
+ width: 'auto',
234
+ marginLeft: 0,
235
+ marginRight: 0,
236
+ marginTop: 0
237
+ });
238
+ break;
239
+
240
+ case 'middle':
241
+ extend(this._node.style, {
242
+ position: 'fixed',
243
+ left: this._offsetToWindow.left + 'px',
244
+ right: this._offsetToWindow.right + 'px',
245
+ top: this._styles.top,
246
+ bottom: 'auto',
247
+ width: 'auto',
248
+ marginLeft: 0,
249
+ marginRight: 0,
250
+ marginTop: 0
251
+ });
252
+ break;
253
+
254
+ case 'end':
255
+ extend(this._node.style, {
256
+ position: 'absolute',
257
+ left: this._offsetToParent.left + 'px',
258
+ right: this._offsetToParent.right + 'px',
259
+ top: 'auto',
260
+ bottom: 0,
261
+ width: 'auto',
262
+ marginLeft: 0,
263
+ marginRight: 0
264
+ });
265
+ break;
266
+ }
267
+
268
+ this._stickyMode = stickyMode;
269
+ }
270
+
271
+ _fastCheck () {
272
+ if (!this._active || this._removed) return;
273
+
274
+ if (
275
+ Math.abs(getDocOffsetTop(this._clone.node) - this._clone.docOffsetTop) > 1 ||
276
+ Math.abs(this._parent.node.offsetHeight - this._parent.offsetHeight) > 1
277
+ ) this.refresh();
278
+ }
279
+
280
+ _deactivate () {
281
+ if (!this._active || this._removed) return;
282
+
283
+ this._clone.node.parentNode.removeChild(this._clone.node);
284
+ delete this._clone;
285
+
286
+ extend(this._node.style, this._styles);
287
+ delete this._styles;
288
+
289
+ // Check whether element’s parent node is used by other stickies.
290
+ // If not, restore parent node’s styles.
291
+ if (!stickies.some(sticky => sticky !== this && sticky._parent && sticky._parent.node === this._parent.node)) {
292
+ extend(this._parent.node.style, this._parent.styles);
293
+ }
294
+ delete this._parent;
295
+
296
+ this._stickyMode = null;
297
+ this._active = false;
298
+
299
+ delete this._offsetToWindow;
300
+ delete this._offsetToParent;
301
+ delete this._limits;
302
+ }
303
+
304
+ remove () {
305
+ this._deactivate();
306
+
307
+ stickies.some((sticky, index) => {
308
+ if (sticky._node === this._node) {
309
+ stickies.splice(index, 1);
310
+ return true;
311
+ }
312
+ });
313
+
314
+ this._removed = true;
315
+ }
316
+ }
317
+
318
+
319
+ /*
320
+ * 5. Stickyfill API
321
+ */
322
+ const Stickyfill = {
323
+ stickies,
324
+ Sticky,
325
+
326
+ addOne (node) {
327
+ // Check whether it’s a node
328
+ if (!(node instanceof HTMLElement)) {
329
+ // Maybe it’s a node list of some sort?
330
+ // Take first node from the list then
331
+ if (node.length && node[0]) node = node[0];
332
+ else return;
333
+ }
334
+
335
+ // Check if Stickyfill is already applied to the node
336
+ // and return existing sticky
337
+ for (var i = 0; i < stickies.length; i++) {
338
+ if (stickies[i]._node === node) return stickies[i];
339
+ }
340
+
341
+ // Create and return new sticky
342
+ return new Sticky(node);
343
+ },
344
+
345
+ add (nodeList) {
346
+ // If it’s a node make an array of one node
347
+ if (nodeList instanceof HTMLElement) nodeList = [nodeList];
348
+ // Check if the argument is an iterable of some sort
349
+ if (!nodeList.length) return;
350
+
351
+ // Add every element as a sticky and return an array of created Sticky instances
352
+ const addedStickies = [];
353
+
354
+ for (let i = 0; i < nodeList.length; i++) {
355
+ const node = nodeList[i];
356
+
357
+ // If it’s not an HTMLElement – create an empty element to preserve 1-to-1
358
+ // correlation with input list
359
+ if (!(node instanceof HTMLElement)) {
360
+ addedStickies.push(void 0);
361
+ continue;
362
+ }
363
+
364
+ // If Stickyfill is already applied to the node
365
+ // add existing sticky
366
+ if (stickies.some(sticky => {
367
+ if (sticky._node === node) {
368
+ addedStickies.push(sticky);
369
+ return true;
370
+ }
371
+ })) continue;
372
+
373
+ // Create and add new sticky
374
+ addedStickies.push(new Sticky(node));
375
+ }
376
+
377
+ return addedStickies;
378
+ },
379
+
380
+ refreshAll () {
381
+ stickies.forEach(sticky => sticky.refresh());
382
+ },
383
+
384
+ removeOne (node) {
385
+ // Check whether it’s a node
386
+ if (!(node instanceof HTMLElement)) {
387
+ // Maybe it’s a node list of some sort?
388
+ // Take first node from the list then
389
+ if (node.length && node[0]) node = node[0];
390
+ else return;
391
+ }
392
+
393
+ // Remove the stickies bound to the nodes in the list
394
+ stickies.some(sticky => {
395
+ if (sticky._node === node) {
396
+ sticky.remove();
397
+ return true;
398
+ }
399
+ });
400
+ },
401
+
402
+ remove (nodeList) {
403
+ // If it’s a node make an array of one node
404
+ if (nodeList instanceof HTMLElement) nodeList = [nodeList];
405
+ // Check if the argument is an iterable of some sort
406
+ if (!nodeList.length) return;
407
+
408
+ // Remove the stickies bound to the nodes in the list
409
+ for (let i = 0; i < nodeList.length; i++) {
410
+ const node = nodeList[i];
411
+
412
+ stickies.some(sticky => {
413
+ if (sticky._node === node) {
414
+ sticky.remove();
415
+ return true;
416
+ }
417
+ });
418
+ }
419
+ },
420
+
421
+ removeAll () {
422
+ while (stickies.length) stickies[0].remove();
423
+ }
424
+ };
425
+
426
+
427
+ /*
428
+ * 6. Setup events (unless the polyfill was disabled)
429
+ */
430
+ function init () {
431
+ // Watch for scroll position changes and trigger recalc/refresh if needed
432
+ function checkScroll () {
433
+ if (window.pageXOffset != scroll.left) {
434
+ scroll.top = window.pageYOffset;
435
+ scroll.left = window.pageXOffset;
436
+
437
+ Stickyfill.refreshAll();
438
+ }
439
+ else if (window.pageYOffset != scroll.top) {
440
+ scroll.top = window.pageYOffset;
441
+ scroll.left = window.pageXOffset;
442
+
443
+ // recalc position for all stickies
444
+ stickies.forEach(sticky => sticky._recalcPosition());
445
+ }
446
+ }
447
+
448
+ checkScroll();
449
+ window.addEventListener('scroll', checkScroll);
450
+
451
+ // Watch for window resizes and device orientation changes and trigger refresh
452
+ window.addEventListener('resize', Stickyfill.refreshAll);
453
+ window.addEventListener('orientationchange', Stickyfill.refreshAll);
454
+
455
+ //Fast dirty check for layout changes every 500ms
456
+ let fastCheckTimer;
457
+
458
+ function startFastCheckTimer () {
459
+ fastCheckTimer = setInterval(function () {
460
+ stickies.forEach(sticky => sticky._fastCheck());
461
+ }, 500);
462
+ }
463
+
464
+ function stopFastCheckTimer () {
465
+ clearInterval(fastCheckTimer);
466
+ }
467
+
468
+ let docHiddenKey;
469
+ let visibilityChangeEventName;
470
+
471
+ if ('hidden' in document) {
472
+ docHiddenKey = 'hidden';
473
+ visibilityChangeEventName = 'visibilitychange';
474
+ }
475
+ else if ('webkitHidden' in document) {
476
+ docHiddenKey = 'webkitHidden';
477
+ visibilityChangeEventName = 'webkitvisibilitychange';
478
+ }
479
+
480
+ if (visibilityChangeEventName) {
481
+ if (!document[docHiddenKey]) startFastCheckTimer();
482
+
483
+ document.addEventListener(visibilityChangeEventName, () => {
484
+ if (document[docHiddenKey]) {
485
+ stopFastCheckTimer();
486
+ }
487
+ else {
488
+ startFastCheckTimer();
489
+ }
490
+ });
491
+ }
492
+ else startFastCheckTimer();
493
+ }
494
+
495
+ if (!seppuku) init();
496
+
497
+
498
+ /*
499
+ * 7. Expose Stickyfill
500
+ */
501
+ if (typeof module != 'undefined' && module.exports) {
502
+ module.exports = Stickyfill;
503
+ }
504
+ else {
505
+ window.Stickyfill = Stickyfill;
506
+ }
507
+