station 0.0.109 → 0.0.114

Sign up to get free protection for your applications and to get access to all the features.
Files changed (121) hide show
  1. checksums.yaml +4 -4
  2. data/Dockerfile +9 -7
  3. data/Gemfile +1 -1
  4. data/Gemfile.lock +2 -2
  5. data/docs/How-To-Use.md +2 -0
  6. data/lib/nexmo_developer/.nvmrc +1 -1
  7. data/lib/nexmo_developer/.ruby-version +1 -1
  8. data/lib/nexmo_developer/Gemfile +17 -28
  9. data/lib/nexmo_developer/Gemfile.lock +107 -119
  10. data/lib/nexmo_developer/Runbook.md +4 -4
  11. data/lib/nexmo_developer/app/assets/config/manifest.js +1 -4
  12. data/lib/nexmo_developer/app/assets/javascripts/application.js +2 -7
  13. data/lib/nexmo_developer/app/assets/stylesheets/application.css +1 -1
  14. data/lib/nexmo_developer/app/controllers/dashboard_controller.rb +0 -5
  15. data/lib/nexmo_developer/app/controllers/jobs_controller.rb +7 -7
  16. data/lib/nexmo_developer/app/controllers/static_controller.rb +5 -14
  17. data/lib/nexmo_developer/app/models/feedback/feedback.rb +2 -0
  18. data/lib/nexmo_developer/app/presenters/head.rb +5 -1
  19. data/lib/nexmo_developer/app/presenters/improve_page_presenter.rb +10 -7
  20. data/lib/nexmo_developer/app/services/orbit_feedback_notifier.rb +53 -0
  21. data/lib/nexmo_developer/app/services/translator/files_list_coordinator.rb +1 -1
  22. data/lib/nexmo_developer/app/services/translator/smartling/api/download_file.rb +6 -1
  23. data/lib/nexmo_developer/app/services/translator/smartling/api/file_status.rb +7 -1
  24. data/lib/nexmo_developer/app/services/translator/utils.rb +1 -1
  25. data/lib/nexmo_developer/app/views/contribute/guides/landing-pages.md +0 -10
  26. data/lib/nexmo_developer/app/views/contribute/guides/markdown-guide.md +36 -40
  27. data/lib/nexmo_developer/app/views/contribute/guides/platform.md +0 -1
  28. data/lib/nexmo_developer/app/views/dashboard/stats.html.erb +2 -2
  29. data/lib/nexmo_developer/app/views/layouts/partials/_head.html.erb +0 -5
  30. data/lib/nexmo_developer/app/views/static/default_landing/partials/_join_slack.html.erb +1 -1
  31. data/lib/nexmo_developer/app/views/static/{robots.txt.erb → robots.text.erb} +0 -0
  32. data/lib/nexmo_developer/app/webpacker/fonts/Lato-Black.woff +0 -0
  33. data/lib/nexmo_developer/app/webpacker/fonts/Lato-Black.woff2 +0 -0
  34. data/lib/nexmo_developer/app/webpacker/fonts/Lato-Regular.woff +0 -0
  35. data/lib/nexmo_developer/app/webpacker/fonts/Lato-Regular.woff2 +0 -0
  36. data/lib/nexmo_developer/app/webpacker/fonts/Lato-Semibold.woff +0 -0
  37. data/lib/nexmo_developer/app/webpacker/fonts/Lato-Semibold.woff2 +0 -0
  38. data/lib/nexmo_developer/app/webpacker/fonts/icomoon.eot +0 -0
  39. data/lib/nexmo_developer/app/webpacker/fonts/icomoon.json +1257 -0
  40. data/lib/nexmo_developer/app/webpacker/fonts/icomoon.svg +55 -0
  41. data/lib/nexmo_developer/app/webpacker/fonts/icomoon.ttf +0 -0
  42. data/lib/nexmo_developer/app/webpacker/fonts/icomoon.woff +0 -0
  43. data/lib/nexmo_developer/app/{assets → webpacker}/images/.keep +0 -0
  44. data/lib/nexmo_developer/app/{assets → webpacker}/images/logo@3x.png +0 -0
  45. data/lib/nexmo_developer/app/{assets → webpacker}/images/logo_vonage.png +0 -0
  46. data/lib/nexmo_developer/app/{assets → webpacker}/images/nexmo-developer-logo.svg +0 -0
  47. data/lib/nexmo_developer/app/{assets → webpacker}/images/nexmo-logo-collapsed.svg +0 -0
  48. data/lib/nexmo_developer/app/{assets → webpacker}/images/nexmo-vonage-white.svg +0 -0
  49. data/lib/nexmo_developer/app/{assets → webpacker}/images/posters/chatapp.jpg +0 -0
  50. data/lib/nexmo_developer/app/{assets → webpacker}/images/posters/chatapp_small.png +0 -0
  51. data/lib/nexmo_developer/app/{assets → webpacker}/images/posters/nexmo.jpg +0 -0
  52. data/lib/nexmo_developer/app/{assets → webpacker}/images/posters/numberinsight.jpg +0 -0
  53. data/lib/nexmo_developer/app/{assets → webpacker}/images/posters/numberinsight_small.png +0 -0
  54. data/lib/nexmo_developer/app/{assets → webpacker}/images/posters/sms.jpg +0 -0
  55. data/lib/nexmo_developer/app/{assets → webpacker}/images/posters/sms_small.png +0 -0
  56. data/lib/nexmo_developer/app/{assets → webpacker}/images/posters/verify.jpg +0 -0
  57. data/lib/nexmo_developer/app/{assets → webpacker}/images/posters/verify_small.png +0 -0
  58. data/lib/nexmo_developer/app/{assets → webpacker}/images/posters/voice.jpg +0 -0
  59. data/lib/nexmo_developer/app/{assets → webpacker}/images/posters/voice_small.png +0 -0
  60. data/lib/nexmo_developer/app/{assets → webpacker}/images/select-dropdown.png +0 -0
  61. data/lib/nexmo_developer/app/{assets → webpacker}/images/slack.svg +0 -0
  62. data/lib/nexmo_developer/app/{assets → webpacker}/images/themes/ea/topography.png +0 -0
  63. data/lib/nexmo_developer/app/webpacker/javascript/code_snippet_events/index.js +23 -85
  64. data/lib/nexmo_developer/app/webpacker/javascript/volta/volta.js +5 -1
  65. data/lib/nexmo_developer/app/webpacker/packs/active_admin.js +5 -0
  66. data/lib/nexmo_developer/app/webpacker/packs/active_admin/print.scss +2 -0
  67. data/lib/nexmo_developer/app/webpacker/packs/application.js +12 -3
  68. data/lib/nexmo_developer/app/{assets → webpacker}/stylesheets/active_admin.scss +4 -4
  69. data/lib/nexmo_developer/app/webpacker/stylesheets/application.scss +0 -1
  70. data/lib/nexmo_developer/config/environments/development.rb +1 -1
  71. data/lib/nexmo_developer/config/initializers/active_admin.rb +3 -0
  72. data/lib/nexmo_developer/config/routes.rb +0 -2
  73. data/lib/nexmo_developer/config/webpack/environment.js +10 -0
  74. data/lib/nexmo_developer/config/webpack/plugins/jquery.js +7 -0
  75. data/lib/nexmo_developer/lib/tasks/cache.rake +1 -1
  76. data/lib/nexmo_developer/lib/tasks/careers.rake +1 -1
  77. data/lib/nexmo_developer/lib/tasks/ci.rake +7 -7
  78. data/lib/nexmo_developer/lib/tasks/diff.rake +5 -5
  79. data/lib/nexmo_developer/lib/tasks/documentation.rake +1 -1
  80. data/lib/nexmo_developer/lib/tasks/generate_search_terms.rake +2 -2
  81. data/lib/nexmo_developer/lib/tasks/links.rake +6 -6
  82. data/lib/nexmo_developer/lib/tasks/smartling.rake +1 -1
  83. data/lib/nexmo_developer/nexmo_developer.rb +3 -4
  84. data/lib/nexmo_developer/version.rb +1 -1
  85. data/package.json +29 -23
  86. data/station.gemspec +10 -14
  87. data/yarn.lock +2013 -3375
  88. metadata +206 -232
  89. data/lib/nexmo_developer/.dockerignore +0 -1
  90. data/lib/nexmo_developer/Dockerfile +0 -28
  91. data/lib/nexmo_developer/app/assets/javascripts/active_admin.js.coffee +0 -1
  92. data/lib/nexmo_developer/app/assets/javascripts/stats.js +0 -14
  93. data/lib/nexmo_developer/app/assets/regex/matching_chars.rb +0 -1
  94. data/lib/nexmo_developer/app/assets/regex/sequence_diagram_regex.rb +0 -1
  95. data/lib/nexmo_developer/app/assets/regex/stats_regex.rb +0 -1
  96. data/lib/nexmo_developer/app/assets/regex/webfont_regex.rb +0 -1
  97. data/lib/nexmo_developer/app/screenshots/webhook-url-for-delivery-receipt.js +0 -44
  98. data/lib/nexmo_developer/app/screenshots/webhook-url-for-inbound-message.js +0 -44
  99. data/lib/nexmo_developer/app/views/static/default_landing/partials/_submit_your_idea_form.html.erb +0 -58
  100. data/lib/nexmo_developer/app/webpacker/javascript/spotlight/index.js +0 -12
  101. data/lib/nexmo_developer/app/webpacker/stylesheets/objects/_building-block.scss +0 -32
  102. data/lib/nexmo_developer/docker-compose.yml +0 -43
  103. data/lib/nexmo_developer/lib/tasks/screenshots.rake +0 -11
  104. data/lib/nexmo_developer/vendor/assets/javascripts/jquery-scrolltofixed.js +0 -567
  105. data/lib/nexmo_developer/vendor/assets/javascripts/mermaid.js +0 -49
  106. data/lib/nexmo_developer/vendor/assets/javascripts/underscore.js +0 -5
  107. data/lib/nexmo_developer/vendor/assets/javascripts/volta/addons/jquery.tablesorter.js +0 -1031
  108. data/lib/nexmo_developer/vendor/assets/javascripts/volta/addons/prism.js +0 -22
  109. data/lib/nexmo_developer/vendor/assets/javascripts/volta/components/side-navigation/volta.menu.js +0 -377
  110. data/lib/nexmo_developer/vendor/assets/javascripts/volta/components/volta.accordion.js +0 -249
  111. data/lib/nexmo_developer/vendor/assets/javascripts/volta/components/volta.dropdown.js +0 -145
  112. data/lib/nexmo_developer/vendor/assets/javascripts/volta/components/volta.flash.js +0 -175
  113. data/lib/nexmo_developer/vendor/assets/javascripts/volta/components/volta.modal.js +0 -312
  114. data/lib/nexmo_developer/vendor/assets/javascripts/volta/components/volta.tab.js +0 -203
  115. data/lib/nexmo_developer/vendor/assets/javascripts/volta/components/volta.tooltip.js +0 -71
  116. data/lib/nexmo_developer/vendor/assets/javascripts/volta/popper.min.js +0 -5
  117. data/lib/nexmo_developer/vendor/assets/javascripts/volta/svgxuse.min.js +0 -12
  118. data/lib/nexmo_developer/vendor/assets/javascripts/volta/tooltip.min.js +0 -5
  119. data/lib/nexmo_developer/vendor/assets/javascripts/volta/volta.core.js +0 -238
  120. data/lib/nexmo_developer/vendor/assets/javascripts/volta/volta.js +0 -2141
  121. data/lib/nexmo_developer/vendor/assets/javascripts/volta/volta.min.js +0 -1
@@ -1 +0,0 @@
1
- public/packs
@@ -1,28 +0,0 @@
1
- # Base image:
2
- FROM ruby:2.7.2
3
-
4
- # Install dependencies
5
- RUN apt-get update -qq && apt-get install -y build-essential libpq-dev lsof
6
-
7
- # Install modern NodeJS
8
- run curl -sL https://deb.nodesource.com/setup_12.x | bash -
9
- run curl -sS https://dl.yarnpkg.com/debian/pubkey.gpg | apt-key add -
10
- run echo "deb https://dl.yarnpkg.com/debian/ stable main" | tee /etc/apt/sources.list.d/yarn.list
11
- run apt-get update && apt-get install -y nodejs yarn
12
-
13
- # Set an environment variable where the Rails app is installed to inside of Docker image:
14
- RUN mkdir -p /app/.git/hooks
15
-
16
- WORKDIR /app
17
-
18
- # Install Node Dependencies
19
- ADD package.json yarn.lock /app/
20
- RUN yarn install
21
-
22
- # Update Bundler to Version 2 as ruby:2.5.5 defaults to an older version
23
- RUN gem update --system && gem install bundler
24
-
25
- # Install Ruby Dependencies
26
- ADD Gemfile /app/Gemfile
27
- ADD Gemfile.lock /app/Gemfile.lock
28
- RUN bundle install
@@ -1 +0,0 @@
1
- #= require active_admin/base
@@ -1,14 +0,0 @@
1
- // This is a manifest file that'll be compiled into application.js, which will include all the files
2
- // listed below.
3
- //
4
- // Any JavaScript/Coffee file within this directory, lib/assets/javascripts, vendor/assets/javascripts,
5
- // or any plugin's vendor/assets/javascripts directory can be referenced here using a relative path.
6
- //
7
- // It's not advisable to add code directly here, but if you do, it'll appear at the bottom of the
8
- // compiled file. JavaScript code in this file should be added after the last require_* statement.
9
- //
10
- // Read Sprockets README (https://github.com/rails/sprockets#sprockets-directives) for details
11
- // about supported directives.
12
- //
13
- //= require Chart.bundle
14
- //= require chartkick
@@ -1 +0,0 @@
1
- /\.(?:svg|eot|woff|ttf)$/
@@ -1 +0,0 @@
1
- %w[sequence-diagram-min.js]
@@ -1 +0,0 @@
1
- %w[stats.js]
@@ -1 +0,0 @@
1
- %w[webfont.js]
@@ -1,44 +0,0 @@
1
- const puppeteer = require('puppeteer');
2
- const fs = require('fs');
3
- const sha1File = require('sha1-file');
4
- require('dotenv').config();
5
-
6
- if (!fs.existsSync('./public/assets/screenshots')){
7
- fs.mkdirSync('./public/assets/screenshots');
8
- }
9
-
10
- (async () => {
11
- const browser = await puppeteer.launch();
12
- const page = await browser.newPage();
13
- await page.setViewport({ width: 800, height: 500 })
14
- await page.goto('https://dashboard.nexmo.com/sign-in');
15
-
16
- await page.waitForSelector('input[name=username]')
17
- await page.type('input[name=username]', process.env.NEXMO_USERNAME)
18
- await page.type('input[name=password]', process.env.NEXMO_PASSWORD)
19
- await page.click('#btn_login')
20
-
21
- await page.waitForSelector('#nav-expander')
22
- await page.goto('https://dashboard.nexmo.com/settings');
23
-
24
- await page.waitForSelector('#nav-expander')
25
- await page.click('#httpBaseUrlForDnPost')
26
-
27
- await page.addStyleTag({
28
- content: `
29
- #sysId, #password, #signatureSecret {
30
- filter: blur(5px);
31
- }
32
- `
33
- })
34
-
35
- await page.screenshot({ path: 'public/assets/screenshots/tmp.png' })
36
-
37
- const sha = sha1File('public/assets/screenshots/tmp.png')
38
- const newPath = `public/assets/screenshots/${sha}.png`
39
- fs.renameSync('public/assets/screenshots/tmp.png', newPath)
40
-
41
- await browser.close();
42
-
43
- console.log(newPath);
44
- })();
@@ -1,44 +0,0 @@
1
- const puppeteer = require('puppeteer')
2
- const fs = require('fs')
3
- const sha1File = require('sha1-file')
4
- require('dotenv').config()
5
-
6
- if (!fs.existsSync('./public/assets/screenshots')){
7
- fs.mkdirSync('./public/assets/screenshots')
8
- }
9
-
10
- (async () => {
11
- const browser = await puppeteer.launch()
12
- const page = await browser.newPage()
13
- await page.setViewport({ width: 800, height: 500 })
14
- await page.goto('https://dashboard.nexmo.com/sign-in')
15
-
16
- await page.waitForSelector('input[name=username]')
17
- await page.type('input[name=username]', process.env.NEXMO_USERNAME)
18
- await page.type('input[name=password]', process.env.NEXMO_PASSWORD)
19
- await page.click('#btn_login')
20
-
21
- await page.waitForSelector('#nav-expander')
22
- await page.goto('https://dashboard.nexmo.com/settings')
23
-
24
- await page.waitForSelector('#nav-expander')
25
- await page.click('#httpBaseUrlForMoPost')
26
-
27
- await page.addStyleTag({
28
- content: `
29
- #sysId, #password, #signatureSecret {
30
- filter: blur(5px)
31
- }
32
- `
33
- })
34
-
35
- await page.screenshot({ path: 'public/assets/screenshots/tmp.png' })
36
-
37
- const sha = sha1File('public/assets/screenshots/tmp.png')
38
- const newPath = `public/assets/screenshots/${sha}.png`
39
- fs.renameSync('public/assets/screenshots/tmp.png', newPath)
40
-
41
- await browser.close()
42
-
43
- console.log(newPath)
44
- })()
@@ -1,58 +0,0 @@
1
- <h2 class="Vlt-title--icon" id="<%= local_assigns['header'].parameterize %>">
2
- <svg class="Vlt-<%= local_assigns['icon']['color'] %>"><use xlink:href="<%= "/symbol/volta-icons.svg#Vlt-#{local_assigns['icon']['name']}" %>"></use></svg>
3
- <%= local_assigns['header'].render_markdown(skip_paragraph_surround: true) %>
4
- </h2>
5
-
6
- <%= form_tag('/spotlight', remote: true, id: 'spotlight-form') do %>
7
- <div class="Vlt-form__element">
8
- <%= label_tag 'name', 'Your Name', class: 'Vlt-label' %>
9
- <div class="Vlt-input">
10
- <%= text_field_tag 'name', nil, required: true %>
11
- </div>
12
- </div>
13
-
14
- <div class="Vlt-form__element">
15
- <%= label_tag 'email_address', 'Your Email Address', class: 'Vlt-label' %>
16
- <div class="Vlt-input">
17
- <%= email_field_tag 'email_address', nil, required: true %>
18
- </div>
19
- </div>
20
-
21
- <div class="Vlt-form__element">
22
- <%= label_tag 'background', 'Please write a little about your background and why you want to write for Vonage', class: 'Vlt-label' %>
23
- <div class="Vlt-textarea">
24
- <%= text_area_tag 'background', nil, required: true, rows: 4, cols: 50 %>
25
- </div>
26
- </div>
27
-
28
- <div class="Vlt-form__element">
29
- <%= label_tag 'outline', 'The outline of your blog post idea', class: 'Vlt-label' %>
30
- <div class="Vlt-textarea">
31
- <%= text_area_tag 'outline', nil, required: true, rows: 4, cols: 50 %>
32
- </div>
33
- </div>
34
-
35
- <div class="Vlt-form__element">
36
- <%= label_tag 'previous_content', 'Please provide link to something you have written previously', class: 'Vlt-label' %>
37
- <div class="Vlt-input">
38
- <%= url_field_tag 'previous_content', nil %>
39
- </div>
40
- </div>
41
-
42
- <small class="Vlt-form__element__hint">
43
- By submitting your ideas to Vonage Developer Spotlight you accept our <a href='https://www.vonage.com/legal/privacy-policy/'>privacy policy</a>, which sets out how we use your data and the rights you have in respect of your data.
44
- </small>
45
- <%= submit_tag 'Submit', class: 'Vlt-btn Vlt-btn--secondary Vlt-btn--app' %>
46
- <% end %>
47
- <div id='success' class="Vlt-callout Vlt-callout--good Vlt-flash Vlt-flash--small ">
48
- <i></i>
49
- <div class="Vlt-callout__content">
50
- <p>Thanks for your submission, we will review it and get in contact with you shortly</p>
51
- </div>
52
- </div>
53
- <div id='error' class="Vlt-callout Vlt-callout--critical Vlt-flash Vlt-flash--small ">
54
- <i></i>
55
- <div class="Vlt-callout__content">
56
- <p>Something went wrong with your submission. Please try again. If the error persists then please email your submission to deved@vonage.com</p>
57
- </div>
58
- </div>
@@ -1,12 +0,0 @@
1
- import Volta from "../volta/volta.js"
2
-
3
- export default () => {
4
- $(document).ready(function() {
5
- $(document).on('ajax:success', '#spotlight-form', function(event, response) {
6
- Volta.flash.show('success');
7
- event.target.reset();
8
- }).on('ajax:error', '#spotlight-form', function(event) {
9
- Volta.flash.show('error');
10
- });
11
- });
12
- }
@@ -1,32 +0,0 @@
1
- .copy-button {
2
- background: $blue;
3
- width: 140px;
4
- height: 24px;
5
- padding-top: 3px;
6
- text-align: center;
7
- clear: both;
8
- color: $white;
9
- font-size: 0.8em;
10
- cursor: pointer;
11
- font-weight: bold;
12
- position: absolute;
13
- top: 0px;
14
- right: 0px;
15
- z-index: 50;
16
- }
17
-
18
- .octicon {
19
- display: inline-block;
20
- vertical-align: text-top;
21
- fill: $white;
22
- }
23
-
24
- .copy-wrapper {
25
- position: relative;
26
- top: auto;
27
- left: auto;
28
- }
29
-
30
- .copy-wrapper pre {
31
- margin-top: 10px;
32
- }
@@ -1,43 +0,0 @@
1
- version: '3'
2
- services:
3
- db:
4
- image: postgres
5
- environment:
6
- - POSTGRES_HOST_AUTH_METHOD=trust
7
- web:
8
- image: nexmodeveloper_app
9
- build: .
10
- command: bundle exec rails s -p 3000 -b '0.0.0.0'
11
- volumes:
12
- - .:/app
13
- - /app/node_modules
14
- ports:
15
- - "3000:3000"
16
- depends_on:
17
- - clean
18
- - update
19
- - db
20
- environment:
21
- - OAS_PATH=_open_api/api_specs/definitions
22
- - DOCS_BASE_PATH=.
23
- - POSTGRES_HOST=db
24
- - POSTGRES_USERNAME=postgres
25
- - RAILS_ENV=development
26
- - RACK_ENV=development
27
- clean:
28
- image: nexmodeveloper_app
29
- build: .
30
- command: bash -c "rm -Rf public/packs && rm -f /app/tmp/pids/server.pid"
31
- volumes:
32
- - .:/app
33
- update:
34
- image: nexmodeveloper_app
35
- build: .
36
- command: bash -c "rake db:setup"
37
- volumes:
38
- - .:/app
39
- depends_on:
40
- - db
41
- environment:
42
- - POSTGRES_HOST=db
43
- - POSTGRES_USERNAME=postgres
@@ -1,11 +0,0 @@
1
- namespace :screenshots do
2
- desc 'Update all automated screenshots'
3
- task all: :environment do
4
- Screenshot.update_all
5
- end
6
-
7
- desc 'Create new screenshots'
8
- task new: :environment do
9
- Screenshot.update_new
10
- end
11
- end
@@ -1,567 +0,0 @@
1
- /*
2
- * ScrollToFixed
3
- * https://github.com/bigspotteddog/ScrollToFixed
4
- *
5
- * Copyright (c) 2011 Joseph Cava-Lynch
6
- * MIT license
7
- */
8
- (function($) {
9
- $.isScrollToFixed = function(el) {
10
- return !!$(el).data('ScrollToFixed');
11
- };
12
-
13
- $.ScrollToFixed = function(el, options) {
14
- // To avoid scope issues, use 'base' instead of 'this' to reference this
15
- // class from internal events and functions.
16
- var base = this;
17
-
18
- // Access to jQuery and DOM versions of element.
19
- base.$el = $(el);
20
- base.el = el;
21
-
22
- // Add a reverse reference to the DOM object.
23
- base.$el.data('ScrollToFixed', base);
24
-
25
- // A flag so we know if the scroll has been reset.
26
- var isReset = false;
27
-
28
- // The element that was given to us to fix if scrolled above the top of
29
- // the page.
30
- var target = base.$el;
31
-
32
- var position;
33
- var originalPosition;
34
- var originalFloat;
35
- var originalOffsetTop;
36
- var originalZIndex;
37
-
38
- // The offset top of the element when resetScroll was called. This is
39
- // used to determine if we have scrolled past the top of the element.
40
- var offsetTop = 0;
41
-
42
- // The offset left of the element when resetScroll was called. This is
43
- // used to move the element left or right relative to the horizontal
44
- // scroll.
45
- var offsetLeft = 0;
46
- var originalOffsetLeft = -1;
47
-
48
- // This last offset used to move the element horizontally. This is used
49
- // to determine if we need to move the element because we would not want
50
- // to do that for no reason.
51
- var lastOffsetLeft = -1;
52
-
53
- // This is the element used to fill the void left by the target element
54
- // when it goes fixed; otherwise, everything below it moves up the page.
55
- var spacer = null;
56
-
57
- var spacerClass;
58
-
59
- var className;
60
-
61
- // Capture the original offsets for the target element. This needs to be
62
- // called whenever the page size changes or when the page is first
63
- // scrolled. For some reason, calling this before the page is first
64
- // scrolled causes the element to become fixed too late.
65
- function resetScroll() {
66
- // Set the element to it original positioning.
67
- target.trigger('preUnfixed.ScrollToFixed');
68
- setUnfixed();
69
- target.trigger('unfixed.ScrollToFixed');
70
-
71
- // Reset the last offset used to determine if the page has moved
72
- // horizontally.
73
- lastOffsetLeft = -1;
74
-
75
- // Capture the offset top of the target element.
76
- offsetTop = target.offset().top;
77
-
78
- // Capture the offset left of the target element.
79
- offsetLeft = target.offset().left;
80
-
81
- // If the offsets option is on, alter the left offset.
82
- if (base.options.offsets) {
83
- offsetLeft += (target.offset().left - target.position().left);
84
- }
85
-
86
- if (originalOffsetLeft == -1) {
87
- originalOffsetLeft = offsetLeft;
88
- }
89
-
90
- position = target.css('position');
91
-
92
- // Set that this has been called at least once.
93
- isReset = true;
94
-
95
- if (base.options.bottom != -1) {
96
- target.trigger('preFixed.ScrollToFixed');
97
- setFixed();
98
- target.trigger('fixed.ScrollToFixed');
99
- }
100
- }
101
-
102
- function getLimit() {
103
- var limit = base.options.limit;
104
- if (!limit) return 0;
105
-
106
- if (typeof(limit) === 'function') {
107
- return limit.apply(target);
108
- }
109
- return limit;
110
- }
111
-
112
- // Returns whether the target element is fixed or not.
113
- function isFixed() {
114
- return position === 'fixed';
115
- }
116
-
117
- // Returns whether the target element is absolute or not.
118
- function isAbsolute() {
119
- return position === 'absolute';
120
- }
121
-
122
- function isUnfixed() {
123
- return !(isFixed() || isAbsolute());
124
- }
125
-
126
- // Sets the target element to fixed. Also, sets the spacer to fill the
127
- // void left by the target element.
128
- function setFixed() {
129
- // Only fix the target element and the spacer if we need to.
130
- if (!isFixed()) {
131
- //get REAL dimensions (decimal fix)
132
- //Ref. http://stackoverflow.com/questions/3603065/how-to-make-jquery-to-not-round-value-returned-by-width
133
- var dimensions = target[0].getBoundingClientRect();
134
-
135
- // Set the spacer to fill the height and width of the target
136
- // element, then display it.
137
- spacer.css({
138
- 'display' : target.css('display'),
139
- 'width' : dimensions.width,
140
- 'height' : dimensions.height,
141
- 'float' : target.css('float')
142
- });
143
-
144
- // Set the target element to fixed and set its width so it does
145
- // not fill the rest of the page horizontally. Also, set its top
146
- // to the margin top specified in the options.
147
-
148
- cssOptions={
149
- 'z-index' : base.options.zIndex,
150
- 'position' : 'fixed',
151
- 'top' : base.options.bottom == -1?getMarginTop():'',
152
- 'bottom' : base.options.bottom == -1?'':base.options.bottom,
153
- 'margin-left' : '0px'
154
- }
155
- if (!base.options.dontSetWidth){ cssOptions['width']=target.css('width'); };
156
-
157
- target.css(cssOptions);
158
-
159
- target.addClass(base.options.baseClassName);
160
-
161
- if (base.options.className) {
162
- target.addClass(base.options.className);
163
- }
164
-
165
- position = 'fixed';
166
- }
167
- }
168
-
169
- function setAbsolute() {
170
-
171
- var top = getLimit();
172
- var left = offsetLeft;
173
-
174
- if (base.options.removeOffsets) {
175
- left = '';
176
- top = top - offsetTop;
177
- }
178
-
179
- cssOptions={
180
- 'position' : 'absolute',
181
- 'top' : top,
182
- 'left' : left,
183
- 'margin-left' : '0px',
184
- 'bottom' : ''
185
- }
186
- if (!base.options.dontSetWidth){ cssOptions['width']=target.css('width'); };
187
-
188
- target.css(cssOptions);
189
-
190
- position = 'absolute';
191
- }
192
-
193
- // Sets the target element back to unfixed. Also, hides the spacer.
194
- function setUnfixed() {
195
- // Only unfix the target element and the spacer if we need to.
196
- if (!isUnfixed()) {
197
- lastOffsetLeft = -1;
198
-
199
- // Hide the spacer now that the target element will fill the
200
- // space.
201
- spacer.css('display', 'none');
202
-
203
- // Remove the style attributes that were added to the target.
204
- // This will reverse the target back to the its original style.
205
- target.css({
206
- 'z-index' : originalZIndex,
207
- 'width' : '',
208
- 'position' : originalPosition,
209
- 'left' : '',
210
- 'top' : originalOffsetTop,
211
- 'margin-left' : ''
212
- });
213
-
214
- target.removeClass('scroll-to-fixed-fixed');
215
-
216
- if (base.options.className) {
217
- target.removeClass(base.options.className);
218
- }
219
-
220
- position = null;
221
- }
222
- }
223
-
224
- // Moves the target element left or right relative to the horizontal
225
- // scroll position.
226
- function setLeft(x) {
227
- // Only if the scroll is not what it was last time we did this.
228
- if (x != lastOffsetLeft) {
229
- // Move the target element horizontally relative to its original
230
- // horizontal position.
231
- target.css('left', offsetLeft - x);
232
-
233
- // Hold the last horizontal position set.
234
- lastOffsetLeft = x;
235
- }
236
- }
237
-
238
- function getMarginTop() {
239
- var marginTop = base.options.marginTop;
240
- if (!marginTop) return 0;
241
-
242
- if (typeof(marginTop) === 'function') {
243
- return marginTop.apply(target);
244
- }
245
- return marginTop;
246
- }
247
-
248
- // Checks to see if we need to do something based on new scroll position
249
- // of the page.
250
- function checkScroll() {
251
- if (!$.isScrollToFixed(target) || target.is(':hidden')) return;
252
- var wasReset = isReset;
253
- var wasUnfixed = isUnfixed();
254
-
255
- // If resetScroll has not yet been called, call it. This only
256
- // happens once.
257
- if (!isReset) {
258
- resetScroll();
259
- } else if (isUnfixed()) {
260
- // if the offset has changed since the last scroll,
261
- // we need to get it again.
262
-
263
- // Capture the offset top of the target element.
264
- offsetTop = target.offset().top;
265
-
266
- // Capture the offset left of the target element.
267
- offsetLeft = target.offset().left;
268
- }
269
-
270
- // Grab the current horizontal scroll position.
271
- var x = $(window).scrollLeft();
272
-
273
- // Grab the current vertical scroll position.
274
- var y = $(window).scrollTop();
275
-
276
- // Get the limit, if there is one.
277
- var limit = getLimit();
278
-
279
- // If the vertical scroll position, plus the optional margin, would
280
- // put the target element at the specified limit, set the target
281
- // element to absolute.
282
- if (base.options.minWidth && $(window).width() < base.options.minWidth) {
283
- if (!isUnfixed() || !wasReset) {
284
- postPosition();
285
- target.trigger('preUnfixed.ScrollToFixed');
286
- setUnfixed();
287
- target.trigger('unfixed.ScrollToFixed');
288
- }
289
- } else if (base.options.maxWidth && $(window).width() > base.options.maxWidth) {
290
- if (!isUnfixed() || !wasReset) {
291
- postPosition();
292
- target.trigger('preUnfixed.ScrollToFixed');
293
- setUnfixed();
294
- target.trigger('unfixed.ScrollToFixed');
295
- }
296
- } else if (base.options.bottom == -1) {
297
- // If the vertical scroll position, plus the optional margin, would
298
- // put the target element at the specified limit, set the target
299
- // element to absolute.
300
- if (limit > 0 && y >= limit - getMarginTop()) {
301
- if (!wasUnfixed && (!isAbsolute() || !wasReset)) {
302
- postPosition();
303
- target.trigger('preAbsolute.ScrollToFixed');
304
- setAbsolute();
305
- target.trigger('unfixed.ScrollToFixed');
306
- }
307
- // If the vertical scroll position, plus the optional margin, would
308
- // put the target element above the top of the page, set the target
309
- // element to fixed.
310
- } else if (y >= offsetTop - getMarginTop()) {
311
- if (!isFixed() || !wasReset) {
312
- postPosition();
313
- target.trigger('preFixed.ScrollToFixed');
314
-
315
- // Set the target element to fixed.
316
- setFixed();
317
-
318
- // Reset the last offset left because we just went fixed.
319
- lastOffsetLeft = -1;
320
-
321
- target.trigger('fixed.ScrollToFixed');
322
- }
323
- // If the page has been scrolled horizontally as well, move the
324
- // target element accordingly.
325
- setLeft(x);
326
- } else {
327
- // Set the target element to unfixed, placing it where it was
328
- // before.
329
- if (!isUnfixed() || !wasReset) {
330
- postPosition();
331
- target.trigger('preUnfixed.ScrollToFixed');
332
- setUnfixed();
333
- target.trigger('unfixed.ScrollToFixed');
334
- }
335
- }
336
- } else {
337
- if (limit > 0) {
338
- if (y + $(window).height() - target.outerHeight(true) >= limit - (getMarginTop() || -getBottom())) {
339
- if (isFixed()) {
340
- postPosition();
341
- target.trigger('preUnfixed.ScrollToFixed');
342
-
343
- if (originalPosition === 'absolute') {
344
- setAbsolute();
345
- } else {
346
- setUnfixed();
347
- }
348
-
349
- target.trigger('unfixed.ScrollToFixed');
350
- }
351
- } else {
352
- if (!isFixed()) {
353
- postPosition();
354
- target.trigger('preFixed.ScrollToFixed');
355
- setFixed();
356
- }
357
- setLeft(x);
358
- target.trigger('fixed.ScrollToFixed');
359
- }
360
- } else {
361
- setLeft(x);
362
- }
363
- }
364
- }
365
-
366
- function getBottom() {
367
- if (!base.options.bottom) return 0;
368
- return base.options.bottom;
369
- }
370
-
371
- function postPosition() {
372
- var position = target.css('position');
373
-
374
- if (position == 'absolute') {
375
- target.trigger('postAbsolute.ScrollToFixed');
376
- } else if (position == 'fixed') {
377
- target.trigger('postFixed.ScrollToFixed');
378
- } else {
379
- target.trigger('postUnfixed.ScrollToFixed');
380
- }
381
- }
382
-
383
- var windowResize = function(event) {
384
- // Check if the element is visible before updating it's position, which
385
- // improves behavior with responsive designs where this element is hidden.
386
- if(target.is(':visible')) {
387
- isReset = false;
388
- checkScroll();
389
- } else {
390
- // Ensure the spacer is hidden
391
- setUnfixed();
392
- }
393
- }
394
-
395
- var windowScroll = function(event) {
396
- (!!window.requestAnimationFrame) ? requestAnimationFrame(checkScroll) : checkScroll();
397
- }
398
-
399
- // From: http://kangax.github.com/cft/#IS_POSITION_FIXED_SUPPORTED
400
- var isPositionFixedSupported = function() {
401
- var container = document.body;
402
-
403
- if (document.createElement && container && container.appendChild && container.removeChild) {
404
- var el = document.createElement('div');
405
-
406
- if (!el.getBoundingClientRect) return null;
407
-
408
- el.innerHTML = 'x';
409
- el.style.cssText = 'position:fixed;top:100px;';
410
- container.appendChild(el);
411
-
412
- var originalHeight = container.style.height,
413
- originalScrollTop = container.scrollTop;
414
-
415
- container.style.height = '3000px';
416
- container.scrollTop = 500;
417
-
418
- var elementTop = el.getBoundingClientRect().top;
419
- container.style.height = originalHeight;
420
-
421
- var isSupported = (elementTop === 100);
422
- container.removeChild(el);
423
- container.scrollTop = originalScrollTop;
424
-
425
- return isSupported;
426
- }
427
-
428
- return null;
429
- }
430
-
431
- var preventDefault = function(e) {
432
- e = e || window.event;
433
- if (e.preventDefault) {
434
- e.preventDefault();
435
- }
436
- e.returnValue = false;
437
- }
438
-
439
- // Initializes this plugin. Captures the options passed in, turns this
440
- // off for devices that do not support fixed position, adds the spacer,
441
- // and binds to the window scroll and resize events.
442
- base.init = function() {
443
- // Capture the options for this plugin.
444
- base.options = $.extend({}, $.ScrollToFixed.defaultOptions, options);
445
-
446
- originalZIndex = target.css('z-index')
447
-
448
- // Turn off this functionality for devices that do not support it.
449
- // if (!(base.options && base.options.dontCheckForPositionFixedSupport)) {
450
- // var fixedSupported = isPositionFixedSupported();
451
- // if (!fixedSupported) return;
452
- // }
453
-
454
- // Put the target element on top of everything that could be below
455
- // it. This reduces flicker when the target element is transitioning
456
- // to fixed.
457
- base.$el.css('z-index', base.options.zIndex);
458
-
459
- // Create a spacer element to fill the void left by the target
460
- // element when it goes fixed.
461
- spacer = $('<div />');
462
-
463
- position = target.css('position');
464
- originalPosition = target.css('position');
465
- originalFloat = target.css('float');
466
- originalOffsetTop = target.css('top');
467
-
468
- // Place the spacer right after the target element.
469
- if (isUnfixed()) base.$el.after(spacer);
470
-
471
- // Reset the target element offsets when the window is resized, then
472
- // check to see if we need to fix or unfix the target element.
473
- $(window).bind('resize.ScrollToFixed', windowResize);
474
-
475
- // When the window scrolls, check to see if we need to fix or unfix
476
- // the target element.
477
- $(window).bind('scroll.ScrollToFixed', windowScroll);
478
-
479
- // For touch devices, call checkScroll directly rather than
480
- // rAF wrapped windowScroll to animate the element
481
- if ('ontouchmove' in window) {
482
- $(window).bind('touchmove.ScrollToFixed', checkScroll);
483
- }
484
-
485
- if (base.options.preFixed) {
486
- target.bind('preFixed.ScrollToFixed', base.options.preFixed);
487
- }
488
- if (base.options.postFixed) {
489
- target.bind('postFixed.ScrollToFixed', base.options.postFixed);
490
- }
491
- if (base.options.preUnfixed) {
492
- target.bind('preUnfixed.ScrollToFixed', base.options.preUnfixed);
493
- }
494
- if (base.options.postUnfixed) {
495
- target.bind('postUnfixed.ScrollToFixed', base.options.postUnfixed);
496
- }
497
- if (base.options.preAbsolute) {
498
- target.bind('preAbsolute.ScrollToFixed', base.options.preAbsolute);
499
- }
500
- if (base.options.postAbsolute) {
501
- target.bind('postAbsolute.ScrollToFixed', base.options.postAbsolute);
502
- }
503
- if (base.options.fixed) {
504
- target.bind('fixed.ScrollToFixed', base.options.fixed);
505
- }
506
- if (base.options.unfixed) {
507
- target.bind('unfixed.ScrollToFixed', base.options.unfixed);
508
- }
509
-
510
- if (base.options.spacerClass) {
511
- spacer.addClass(base.options.spacerClass);
512
- }
513
-
514
- target.bind('resize.ScrollToFixed', function() {
515
- spacer.height(target.height());
516
- });
517
-
518
- target.bind('scroll.ScrollToFixed', function() {
519
- target.trigger('preUnfixed.ScrollToFixed');
520
- setUnfixed();
521
- target.trigger('unfixed.ScrollToFixed');
522
- checkScroll();
523
- });
524
-
525
- target.bind('detach.ScrollToFixed', function(ev) {
526
- preventDefault(ev);
527
-
528
- target.trigger('preUnfixed.ScrollToFixed');
529
- setUnfixed();
530
- target.trigger('unfixed.ScrollToFixed');
531
-
532
- $(window).unbind('resize.ScrollToFixed', windowResize);
533
- $(window).unbind('scroll.ScrollToFixed', windowScroll);
534
-
535
- target.unbind('.ScrollToFixed');
536
-
537
- //remove spacer from dom
538
- spacer.remove();
539
-
540
- base.$el.removeData('ScrollToFixed');
541
- });
542
-
543
- // Reset everything.
544
- windowResize();
545
- };
546
-
547
- // Initialize the plugin.
548
- base.init();
549
- };
550
-
551
- // Sets the option defaults.
552
- $.ScrollToFixed.defaultOptions = {
553
- marginTop : 0,
554
- limit : 0,
555
- bottom : -1,
556
- zIndex : 1000,
557
- baseClassName: 'scroll-to-fixed-fixed'
558
- };
559
-
560
- // Returns enhanced elements that will fix to the top of the page when the
561
- // page is scrolled.
562
- $.fn.scrollToFixed = function(options) {
563
- return this.each(function() {
564
- (new $.ScrollToFixed(this, options));
565
- });
566
- };
567
- })(jQuery);