idsk_frontend_toolkit 7.4.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +3 -0
- data/.gitmodules +3 -0
- data/.ruby-version +1 -0
- data/.travis/govuk_frontend_toolkit_gem_push.enc +0 -0
- data/.travis/govuk_frontend_toolkit_gem_push.pub +1 -0
- data/.travis.yml +23 -0
- data/CONTRIBUTING.md +13 -0
- data/Gemfile +3 -0
- data/LICENCE +20 -0
- data/README.md +61 -0
- data/Rakefile +10 -0
- data/app/assets/.gitignore +5 -0
- data/app/assets/.ruby-version +1 -0
- data/app/assets/.travis/README.md +23 -0
- data/app/assets/.travis/govuk_frontend_toolkit_push.enc +0 -0
- data/app/assets/.travis/govuk_frontend_toolkit_push.pub +1 -0
- data/app/assets/.travis.yml +18 -0
- data/app/assets/CHANGELOG.md +381 -0
- data/app/assets/CONTRIBUTING.md +23 -0
- data/app/assets/Gemfile +4 -0
- data/app/assets/Gemfile.lock +48 -0
- data/app/assets/Gruntfile.js +68 -0
- data/app/assets/LICENCE +20 -0
- data/app/assets/README.md +170 -0
- data/app/assets/VERSION.txt +1 -0
- data/app/assets/create-release.sh +38 -0
- data/app/assets/docs/analytics.md +270 -0
- data/app/assets/docs/functions.md +62 -0
- data/app/assets/docs/javascript.md +337 -0
- data/app/assets/docs/mixins.md +617 -0
- data/app/assets/images/accordion-arrow-2x.png +0 -0
- data/app/assets/images/accordion-arrow.png +0 -0
- data/app/assets/images/arrow-sprite.png +0 -0
- data/app/assets/images/crests/bis_crest_13px.png +0 -0
- data/app/assets/images/crests/bis_crest_13px_x2.png +0 -0
- data/app/assets/images/crests/bis_crest_18px.png +0 -0
- data/app/assets/images/crests/bis_crest_18px_x2.png +0 -0
- data/app/assets/images/crests/bis_crest_27px.png +0 -0
- data/app/assets/images/crests/bis_crest_27px_x2.png +0 -0
- data/app/assets/images/crests/coastguard_13px.png +0 -0
- data/app/assets/images/crests/coastguard_13px_x2.png +0 -0
- data/app/assets/images/crests/coastguard_18px.png +0 -0
- data/app/assets/images/crests/coastguard_18px_x2.png +0 -0
- data/app/assets/images/crests/coastguard_27px.png +0 -0
- data/app/assets/images/crests/coastguard_27px_x2.png +0 -0
- data/app/assets/images/crests/dit_crest_13px.png +0 -0
- data/app/assets/images/crests/dit_crest_13px_x2.png +0 -0
- data/app/assets/images/crests/dit_crest_18px.png +0 -0
- data/app/assets/images/crests/dit_crest_18px_x2.png +0 -0
- data/app/assets/images/crests/dit_crest_27px.png +0 -0
- data/app/assets/images/crests/dit_crest_27px_x2.png +0 -0
- data/app/assets/images/crests/hmrc_crest_13px.png +0 -0
- data/app/assets/images/crests/hmrc_crest_13px_x2.png +0 -0
- data/app/assets/images/crests/hmrc_crest_18px.png +0 -0
- data/app/assets/images/crests/hmrc_crest_18px_x2.png +0 -0
- data/app/assets/images/crests/hmrc_crest_27px.png +0 -0
- data/app/assets/images/crests/hmrc_crest_27px_x2.png +0 -0
- data/app/assets/images/crests/ho_crest_13px.png +0 -0
- data/app/assets/images/crests/ho_crest_13px_x2.png +0 -0
- data/app/assets/images/crests/ho_crest_18px.png +0 -0
- data/app/assets/images/crests/ho_crest_18px_x2.png +0 -0
- data/app/assets/images/crests/ho_crest_27px.png +0 -0
- data/app/assets/images/crests/ho_crest_27px_x2.png +0 -0
- data/app/assets/images/crests/mod_crest_13px.png +0 -0
- data/app/assets/images/crests/mod_crest_13px_x2.png +0 -0
- data/app/assets/images/crests/mod_crest_18px.png +0 -0
- data/app/assets/images/crests/mod_crest_18px_x2.png +0 -0
- data/app/assets/images/crests/mod_crest_27px.png +0 -0
- data/app/assets/images/crests/mod_crest_27px_x2.png +0 -0
- data/app/assets/images/crests/org_crest_13px.png +0 -0
- data/app/assets/images/crests/org_crest_13px_x2.png +0 -0
- data/app/assets/images/crests/org_crest_18px.png +0 -0
- data/app/assets/images/crests/org_crest_18px_x2.png +0 -0
- data/app/assets/images/crests/org_crest_27px.png +0 -0
- data/app/assets/images/crests/org_crest_27px_x2.png +0 -0
- data/app/assets/images/crests/portcullis_13px.png +0 -0
- data/app/assets/images/crests/portcullis_13px_x2.png +0 -0
- data/app/assets/images/crests/portcullis_18px.png +0 -0
- data/app/assets/images/crests/portcullis_18px_x2.png +0 -0
- data/app/assets/images/crests/portcullis_27px.png +0 -0
- data/app/assets/images/crests/portcullis_27px_x2.png +0 -0
- data/app/assets/images/crests/so_crest_13px.png +0 -0
- data/app/assets/images/crests/so_crest_13px_x2.png +0 -0
- data/app/assets/images/crests/so_crest_18px.png +0 -0
- data/app/assets/images/crests/so_crest_18px_x2.png +0 -0
- data/app/assets/images/crests/so_crest_27px.png +0 -0
- data/app/assets/images/crests/so_crest_27px_x2.png +0 -0
- data/app/assets/images/crests/ukaea_crest_13px.png +0 -0
- data/app/assets/images/crests/ukaea_crest_13px_x2.png +0 -0
- data/app/assets/images/crests/ukaea_crest_18px.png +0 -0
- data/app/assets/images/crests/ukaea_crest_18px_x2.png +0 -0
- data/app/assets/images/crests/ukaea_crest_27px.png +0 -0
- data/app/assets/images/crests/ukaea_crest_27px_x2.png +0 -0
- data/app/assets/images/crests/ukho_13px.png +0 -0
- data/app/assets/images/crests/ukho_13px_x2.png +0 -0
- data/app/assets/images/crests/ukho_18px.png +0 -0
- data/app/assets/images/crests/ukho_18px_x2.png +0 -0
- data/app/assets/images/crests/ukho_27px.png +0 -0
- data/app/assets/images/crests/ukho_27px_x2.png +0 -0
- data/app/assets/images/crests/wales_crest_13px.png +0 -0
- data/app/assets/images/crests/wales_crest_13px_x2.png +0 -0
- data/app/assets/images/crests/wales_crest_18px.png +0 -0
- data/app/assets/images/crests/wales_crest_18px_x2.png +0 -0
- data/app/assets/images/crests/wales_crest_27px.png +0 -0
- data/app/assets/images/crests/wales_crest_27px_x2.png +0 -0
- data/app/assets/images/icon-arrow-left.png +0 -0
- data/app/assets/images/icon-calendar-2x.png +0 -0
- data/app/assets/images/icon-calendar.png +0 -0
- data/app/assets/images/icon-file-download-2x.png +0 -0
- data/app/assets/images/icon-file-download.png +0 -0
- data/app/assets/images/icon-important-2x.png +0 -0
- data/app/assets/images/icon-important.png +0 -0
- data/app/assets/images/icon-information-2x.png +0 -0
- data/app/assets/images/icon-information.png +0 -0
- data/app/assets/images/icon-locator-2x.png +0 -0
- data/app/assets/images/icon-locator.png +0 -0
- data/app/assets/images/icon-pointer-2x.png +0 -0
- data/app/assets/images/icon-pointer-black-2x.png +0 -0
- data/app/assets/images/icon-pointer-black.png +0 -0
- data/app/assets/images/icon-pointer-indexed.png +0 -0
- data/app/assets/images/icon-pointer.png +0 -0
- data/app/assets/images/icon-search-2x.png +0 -0
- data/app/assets/images/icon-search.png +0 -0
- data/app/assets/images/icon-steps/icon-step-1-2x.png +0 -0
- data/app/assets/images/icon-steps/icon-step-1.png +0 -0
- data/app/assets/images/icon-steps/icon-step-10-2x.png +0 -0
- data/app/assets/images/icon-steps/icon-step-10.png +0 -0
- data/app/assets/images/icon-steps/icon-step-11-2x.png +0 -0
- data/app/assets/images/icon-steps/icon-step-11.png +0 -0
- data/app/assets/images/icon-steps/icon-step-12-2x.png +0 -0
- data/app/assets/images/icon-steps/icon-step-12.png +0 -0
- data/app/assets/images/icon-steps/icon-step-13-2x.png +0 -0
- data/app/assets/images/icon-steps/icon-step-13.png +0 -0
- data/app/assets/images/icon-steps/icon-step-14-2x.png +0 -0
- data/app/assets/images/icon-steps/icon-step-14.png +0 -0
- data/app/assets/images/icon-steps/icon-step-2-2x.png +0 -0
- data/app/assets/images/icon-steps/icon-step-2.png +0 -0
- data/app/assets/images/icon-steps/icon-step-3-2x.png +0 -0
- data/app/assets/images/icon-steps/icon-step-3.png +0 -0
- data/app/assets/images/icon-steps/icon-step-4-2x.png +0 -0
- data/app/assets/images/icon-steps/icon-step-4.png +0 -0
- data/app/assets/images/icon-steps/icon-step-5-2x.png +0 -0
- data/app/assets/images/icon-steps/icon-step-5.png +0 -0
- data/app/assets/images/icon-steps/icon-step-6-2x.png +0 -0
- data/app/assets/images/icon-steps/icon-step-6.png +0 -0
- data/app/assets/images/icon-steps/icon-step-7-2x.png +0 -0
- data/app/assets/images/icon-steps/icon-step-7.png +0 -0
- data/app/assets/images/icon-steps/icon-step-8-2x.png +0 -0
- data/app/assets/images/icon-steps/icon-step-8.png +0 -0
- data/app/assets/images/icon-steps/icon-step-9-2x.png +0 -0
- data/app/assets/images/icon-steps/icon-step-9.png +0 -0
- data/app/assets/images/player-icon-forward.png +0 -0
- data/app/assets/images/player-icon-pause.png +0 -0
- data/app/assets/images/player-icon-play.png +0 -0
- data/app/assets/images/player-icon-rewind.png +0 -0
- data/app/assets/images/player-icon-volume.png +0 -0
- data/app/assets/images/separator-2x.png +0 -0
- data/app/assets/images/separator.png +0 -0
- data/app/assets/javascripts/govuk/analytics/analytics.js +143 -0
- data/app/assets/javascripts/govuk/analytics/download-link-tracker.js +41 -0
- data/app/assets/javascripts/govuk/analytics/error-tracking.js +51 -0
- data/app/assets/javascripts/govuk/analytics/external-link-tracker.js +56 -0
- data/app/assets/javascripts/govuk/analytics/google-analytics-universal-tracker.js +166 -0
- data/app/assets/javascripts/govuk/analytics/govuk-tracker.js +134 -0
- data/app/assets/javascripts/govuk/analytics/mailto-link-tracker.js +38 -0
- data/app/assets/javascripts/govuk/analytics/print-intent.js +39 -0
- data/app/assets/javascripts/govuk/details.polyfill.js +240 -0
- data/app/assets/javascripts/govuk/modules/auto-track-event.js +30 -0
- data/app/assets/javascripts/govuk/modules.js +61 -0
- data/app/assets/javascripts/govuk/primary-links.js +57 -0
- data/app/assets/javascripts/govuk/selection-buttons.js +116 -0
- data/app/assets/javascripts/govuk/shim-links-with-button-role.js +34 -0
- data/app/assets/javascripts/govuk/show-hide-content.js +172 -0
- data/app/assets/javascripts/govuk/stick-at-top-when-scrolling.js +128 -0
- data/app/assets/javascripts/govuk/stop-scrolling-at-footer.js +139 -0
- data/app/assets/javascripts/govuk_toolkit.js +1 -0
- data/app/assets/javascripts/stageprompt.js +69 -0
- data/app/assets/javascripts/vendor/jquery/jquery.player.min.js +25 -0
- data/app/assets/javascripts/vendor/polyfills/bind.js +40 -0
- data/app/assets/package.json +25 -0
- data/app/assets/spec/manifest.js +41 -0
- data/app/assets/spec/stylesheets/_colour_contrast_spec.scss +12 -0
- data/app/assets/spec/support/LocalTestRunner.html +21 -0
- data/app/assets/spec/support/console-runner.js +102 -0
- data/app/assets/spec/support/load.js +47 -0
- data/app/assets/spec/support/run_jasmine_test.js +62 -0
- data/app/assets/spec/unit/analytics/analytics.spec.js +315 -0
- data/app/assets/spec/unit/analytics/download-link-tracker.spec.js +72 -0
- data/app/assets/spec/unit/analytics/error-tracking.spec.js +65 -0
- data/app/assets/spec/unit/analytics/external-link-tracker.spec.js +109 -0
- data/app/assets/spec/unit/analytics/google-analytics-universal-tracker.spec.js +180 -0
- data/app/assets/spec/unit/analytics/govuk-tracker.spec.js +171 -0
- data/app/assets/spec/unit/analytics/mailto-link-tracker.spec.js +62 -0
- data/app/assets/spec/unit/details.polyfill.spec.js +91 -0
- data/app/assets/spec/unit/modules/auto-track-event.spec.js +54 -0
- data/app/assets/spec/unit/modules.spec.js +93 -0
- data/app/assets/spec/unit/primary-links.spec.js +55 -0
- data/app/assets/spec/unit/selection-button.spec.js +761 -0
- data/app/assets/spec/unit/shim-links-with-button-role.spec.js +41 -0
- data/app/assets/spec/unit/show-hide-content.spec.js +306 -0
- data/app/assets/spec/unit/stick-at-top-when-scrolling.spec.js +137 -0
- data/app/assets/stylesheets/.gitkeep +0 -0
- data/app/assets/stylesheets/_colours.scss +2 -0
- data/app/assets/stylesheets/_conditionals.scss +81 -0
- data/app/assets/stylesheets/_css3.scss +90 -0
- data/app/assets/stylesheets/_device-pixels.scss +10 -0
- data/app/assets/stylesheets/_font_stack.scss +25 -0
- data/app/assets/stylesheets/_grid_layout.scss +136 -0
- data/app/assets/stylesheets/_helpers.scss +16 -0
- data/app/assets/stylesheets/_measurements.scss +14 -0
- data/app/assets/stylesheets/_shims.scss +55 -0
- data/app/assets/stylesheets/_typography.scss +249 -0
- data/app/assets/stylesheets/_url-helpers.scss +16 -0
- data/app/assets/stylesheets/colours/_organisation.scss +104 -0
- data/app/assets/stylesheets/colours/_palette.scss +77 -0
- data/app/assets/stylesheets/design-patterns/_alpha-beta.scss +67 -0
- data/app/assets/stylesheets/design-patterns/_breadcrumbs.scss +53 -0
- data/app/assets/stylesheets/design-patterns/_buttons.scss +145 -0
- data/app/assets/stylesheets/design-patterns/_media-player.scss +264 -0
- data/app/assets/trigger.sh +24 -0
- data/idsk_frontend_toolkit.gemspec +49 -0
- data/lib/idsk_frontend_toolkit/engine.rb +4 -0
- data/lib/idsk_frontend_toolkit/version.rb +5 -0
- data/lib/idsk_frontend_toolkit.rb +4 -0
- data/publish.sh +30 -0
- metadata +314 -0
@@ -0,0 +1,41 @@
|
|
1
|
+
/* global describe it expect beforeEach afterEach */
|
2
|
+
|
3
|
+
var $ = window.jQuery
|
4
|
+
|
5
|
+
describe('shim-links-with-button-role', function () {
|
6
|
+
'use strict'
|
7
|
+
var GOVUK = window.GOVUK
|
8
|
+
|
9
|
+
var $buttonLink
|
10
|
+
var keyDownEvent
|
11
|
+
|
12
|
+
beforeEach(function () {
|
13
|
+
$buttonLink = $('<a role="button">Button</a>')
|
14
|
+
$buttonLink.on('click', function () {
|
15
|
+
$buttonLink.addClass('clicked')
|
16
|
+
})
|
17
|
+
$(document.body).append($buttonLink)
|
18
|
+
keyDownEvent = $.Event('keydown')
|
19
|
+
keyDownEvent.target = $buttonLink.get(0)
|
20
|
+
GOVUK.shimLinksWithButtonRole.init()
|
21
|
+
})
|
22
|
+
|
23
|
+
afterEach(function () {
|
24
|
+
$buttonLink.remove()
|
25
|
+
$(document).off('keyup')
|
26
|
+
})
|
27
|
+
|
28
|
+
it('should trigger event on space', function () {
|
29
|
+
// Ideally we’d test the page loading functionality but that seems hard to
|
30
|
+
// do within a Jasmine context. Settle for checking a bound event trigger.
|
31
|
+
keyDownEvent.which = 32 // Space character
|
32
|
+
$(document).trigger(keyDownEvent)
|
33
|
+
expect($buttonLink.hasClass('clicked')).toBe(true)
|
34
|
+
})
|
35
|
+
|
36
|
+
it('should not trigger event on tab', function () {
|
37
|
+
keyDownEvent.which = 9 // Tab character
|
38
|
+
$(document).trigger(keyDownEvent)
|
39
|
+
expect($buttonLink.hasClass('clicked')).toBe(false)
|
40
|
+
})
|
41
|
+
})
|
@@ -0,0 +1,306 @@
|
|
1
|
+
/* global describe it expect beforeEach afterEach jasmine */
|
2
|
+
|
3
|
+
var $ = window.jQuery
|
4
|
+
|
5
|
+
describe('show-hide-content', function () {
|
6
|
+
'use strict'
|
7
|
+
var GOVUK = window.GOVUK
|
8
|
+
|
9
|
+
afterEach(function () {
|
10
|
+
if (this.showHideContent) {
|
11
|
+
this.showHideContent.destroy()
|
12
|
+
}
|
13
|
+
|
14
|
+
this.$content.remove()
|
15
|
+
})
|
16
|
+
|
17
|
+
describe('when the radios are inside a form', function () {
|
18
|
+
beforeEach(function () {
|
19
|
+
// Sample markup
|
20
|
+
this.$content = $(
|
21
|
+
|
22
|
+
// Radio buttons (yes/no)
|
23
|
+
'<form>' +
|
24
|
+
'<div class="multiple-choice" data-target="show-hide-radios">' +
|
25
|
+
'<input type="radio" name="single" value="yes">' +
|
26
|
+
'<label>Yes</label>' +
|
27
|
+
'</div>' +
|
28
|
+
'<div class="multiple-choice">' +
|
29
|
+
'<input type="radio" name="single" value="no">' +
|
30
|
+
'<label>No</label>' +
|
31
|
+
'</div>' +
|
32
|
+
'<div id="show-hide-radios" class="panel js-hidden" />' +
|
33
|
+
'</form>' +
|
34
|
+
|
35
|
+
// Checkboxes (multiple values)
|
36
|
+
'<form>' +
|
37
|
+
'<div class="multiple-choice" data-target="show-hide-checkboxes">' +
|
38
|
+
'<input type="checkbox" name="multiple[option1]">' +
|
39
|
+
'<label>Option 1</label>' +
|
40
|
+
'</div>' +
|
41
|
+
'<div class="multiple-choice">' +
|
42
|
+
'<input type="checkbox" name="multiple[option2]">' +
|
43
|
+
'<label>Option 2</label>' +
|
44
|
+
'</div>' +
|
45
|
+
'<div class="multiple-choice">' +
|
46
|
+
'<input type="checkbox" name="multiple[option3]">' +
|
47
|
+
'<label>Option 3</label>' +
|
48
|
+
'</div>' +
|
49
|
+
'<div id="show-hide-checkboxes" class="panel js-hidden" />' +
|
50
|
+
'</form>'
|
51
|
+
)
|
52
|
+
|
53
|
+
// Find radios/checkboxes
|
54
|
+
var $radios = this.$content.find('input[type=radio]')
|
55
|
+
var $checkboxes = this.$content.find('input[type=checkbox]')
|
56
|
+
|
57
|
+
// Two radios
|
58
|
+
this.$radio1 = $radios.eq(0)
|
59
|
+
this.$radio2 = $radios.eq(1)
|
60
|
+
|
61
|
+
// Three checkboxes
|
62
|
+
this.$checkbox1 = $checkboxes.eq(0)
|
63
|
+
this.$checkbox2 = $checkboxes.eq(1)
|
64
|
+
this.$checkbox3 = $checkboxes.eq(2)
|
65
|
+
|
66
|
+
// Add to page
|
67
|
+
$(document.body).append(this.$content)
|
68
|
+
|
69
|
+
// Show/Hide content
|
70
|
+
this.$radioShowHide = $('#show-hide-radios')
|
71
|
+
this.$checkboxShowHide = $('#show-hide-checkboxes')
|
72
|
+
|
73
|
+
// Add show/hide content support
|
74
|
+
this.showHideContent = new GOVUK.ShowHideContent()
|
75
|
+
this.showHideContent.init()
|
76
|
+
})
|
77
|
+
|
78
|
+
describe('and when this.showHideContent = new GOVUK.ShowHideContent() is called', function () {
|
79
|
+
it('should add the aria attributes to inputs with show/hide content', function () {
|
80
|
+
expect(this.$radio1.attr('aria-expanded')).toBe('false')
|
81
|
+
expect(this.$radio1.attr('aria-controls')).toBe('show-hide-radios')
|
82
|
+
})
|
83
|
+
|
84
|
+
it('should add the aria attributes to show/hide content', function () {
|
85
|
+
expect(this.$radioShowHide.attr('aria-hidden')).toBe('true')
|
86
|
+
expect(this.$radioShowHide.hasClass('js-hidden')).toEqual(true)
|
87
|
+
})
|
88
|
+
|
89
|
+
it('should hide the show/hide content visually', function () {
|
90
|
+
expect(this.$radioShowHide.hasClass('js-hidden')).toEqual(true)
|
91
|
+
})
|
92
|
+
|
93
|
+
it('should do nothing if no radios are checked', function () {
|
94
|
+
expect(this.$radio1.attr('aria-expanded')).toBe('false')
|
95
|
+
expect(this.$radio2.attr('aria-expanded')).toBe(undefined)
|
96
|
+
})
|
97
|
+
|
98
|
+
it('should do nothing if no checkboxes are checked', function () {
|
99
|
+
expect(this.$radio1.attr('aria-expanded')).toBe('false')
|
100
|
+
expect(this.$radio2.attr('aria-expanded')).toBe(undefined)
|
101
|
+
})
|
102
|
+
|
103
|
+
describe('with non-default markup', function () {
|
104
|
+
beforeEach(function () {
|
105
|
+
this.showHideContent.destroy()
|
106
|
+
})
|
107
|
+
|
108
|
+
it('should do nothing if a radio without show/hide content is checked', function () {
|
109
|
+
this.$radio2.prop('checked', true)
|
110
|
+
|
111
|
+
// Defaults changed, initialise again
|
112
|
+
this.showHideContent = new GOVUK.ShowHideContent().init()
|
113
|
+
expect(this.$radio1.attr('aria-expanded')).toBe('false')
|
114
|
+
expect(this.$radioShowHide.attr('aria-hidden')).toBe('true')
|
115
|
+
expect(this.$radioShowHide.hasClass('js-hidden')).toEqual(true)
|
116
|
+
})
|
117
|
+
|
118
|
+
it('should do nothing if a checkbox without show/hide content is checked', function () {
|
119
|
+
this.$checkbox2.prop('checked', true)
|
120
|
+
|
121
|
+
// Defaults changed, initialise again
|
122
|
+
this.showHideContent = new GOVUK.ShowHideContent().init()
|
123
|
+
expect(this.$checkbox1.attr('aria-expanded')).toBe('false')
|
124
|
+
expect(this.$checkboxShowHide.attr('aria-hidden')).toBe('true')
|
125
|
+
expect(this.$checkboxShowHide.hasClass('js-hidden')).toEqual(true)
|
126
|
+
})
|
127
|
+
|
128
|
+
it('should do nothing if checkboxes without show/hide content is checked', function () {
|
129
|
+
this.$checkbox2.prop('checked', true)
|
130
|
+
this.$checkbox3.prop('checked', true)
|
131
|
+
|
132
|
+
// Defaults changed, initialise again
|
133
|
+
this.showHideContent = new GOVUK.ShowHideContent().init()
|
134
|
+
expect(this.$checkbox1.attr('aria-expanded')).toBe('false')
|
135
|
+
expect(this.$checkboxShowHide.attr('aria-hidden')).toBe('true')
|
136
|
+
expect(this.$checkboxShowHide.hasClass('js-hidden')).toEqual(true)
|
137
|
+
})
|
138
|
+
|
139
|
+
it('should make the show/hide content visible if its radio is checked', function () {
|
140
|
+
this.$radio1.prop('checked', true)
|
141
|
+
|
142
|
+
// Defaults changed, initialise again
|
143
|
+
this.showHideContent = new GOVUK.ShowHideContent().init()
|
144
|
+
expect(this.$radio1.attr('aria-expanded')).toBe('true')
|
145
|
+
expect(this.$radioShowHide.attr('aria-hidden')).toBe('false')
|
146
|
+
expect(this.$radioShowHide.hasClass('js-hidden')).toEqual(false)
|
147
|
+
})
|
148
|
+
|
149
|
+
it('should make the show/hide content visible if its checkbox is checked', function () {
|
150
|
+
this.$checkbox1.prop('checked', true)
|
151
|
+
|
152
|
+
// Defaults changed, initialise again
|
153
|
+
this.showHideContent = new GOVUK.ShowHideContent().init()
|
154
|
+
expect(this.$checkbox1.attr('aria-expanded')).toBe('true')
|
155
|
+
expect(this.$checkboxShowHide.attr('aria-hidden')).toBe('false')
|
156
|
+
expect(this.$checkboxShowHide.hasClass('js-hidden')).toEqual(false)
|
157
|
+
})
|
158
|
+
})
|
159
|
+
|
160
|
+
describe('and a show/hide radio receives a click', function () {
|
161
|
+
it('should make the show/hide content visible', function () {
|
162
|
+
this.$radio1.click()
|
163
|
+
expect(this.$radioShowHide.hasClass('js-hidden')).toEqual(false)
|
164
|
+
})
|
165
|
+
|
166
|
+
it('should add the aria attributes to show/hide content', function () {
|
167
|
+
this.$radio1.click()
|
168
|
+
expect(this.$radio1.attr('aria-expanded')).toBe('true')
|
169
|
+
expect(this.$radioShowHide.attr('aria-hidden')).toBe('false')
|
170
|
+
expect(this.$radioShowHide.hasClass('js-hidden')).toEqual(false)
|
171
|
+
})
|
172
|
+
})
|
173
|
+
|
174
|
+
describe('and a show/hide checkbox receives a click', function () {
|
175
|
+
it('should make the show/hide content visible', function () {
|
176
|
+
this.$checkbox1.click()
|
177
|
+
expect(this.$checkboxShowHide.hasClass('js-hidden')).toEqual(false)
|
178
|
+
})
|
179
|
+
|
180
|
+
it('should add the aria attributes to show/hide content', function () {
|
181
|
+
this.$checkbox1.click()
|
182
|
+
expect(this.$checkbox1.attr('aria-expanded')).toBe('true')
|
183
|
+
expect(this.$checkboxShowHide.attr('aria-hidden')).toBe('false')
|
184
|
+
expect(this.$checkboxShowHide.hasClass('js-hidden')).toEqual(false)
|
185
|
+
})
|
186
|
+
})
|
187
|
+
|
188
|
+
describe('and a show/hide radio receives a click, but another group radio is clicked afterwards', function () {
|
189
|
+
it('should make the show/hide content hidden', function () {
|
190
|
+
this.$radio1.click()
|
191
|
+
this.$radio2.click()
|
192
|
+
expect(this.$radioShowHide.hasClass('js-hidden')).toEqual(true)
|
193
|
+
})
|
194
|
+
|
195
|
+
it('should add the aria attributes to show/hide content', function () {
|
196
|
+
this.$radio1.click()
|
197
|
+
this.$radio2.click()
|
198
|
+
expect(this.$radio1.attr('aria-expanded')).toBe('false')
|
199
|
+
expect(this.$radioShowHide.attr('aria-hidden')).toBe('true')
|
200
|
+
})
|
201
|
+
})
|
202
|
+
|
203
|
+
describe('and a show/hide checkbox receives a click, but another checkbox is clicked afterwards', function () {
|
204
|
+
it('should keep the show/hide content visible', function () {
|
205
|
+
this.$checkbox1.click()
|
206
|
+
this.$checkbox2.click()
|
207
|
+
expect(this.$checkboxShowHide.hasClass('js-hidden')).toEqual(false)
|
208
|
+
})
|
209
|
+
|
210
|
+
it('should keep the aria attributes to show/hide content', function () {
|
211
|
+
this.$checkbox1.click()
|
212
|
+
this.$checkbox2.click()
|
213
|
+
expect(this.$checkbox1.attr('aria-expanded')).toBe('true')
|
214
|
+
expect(this.$checkboxShowHide.attr('aria-hidden')).toBe('false')
|
215
|
+
})
|
216
|
+
})
|
217
|
+
})
|
218
|
+
|
219
|
+
describe('before this.showHideContent.destroy() is called', function () {
|
220
|
+
it('document.body should have show/hide event handlers', function () {
|
221
|
+
var events = $._data(document.body, 'events')
|
222
|
+
expect(events && events.click).toContain(jasmine.objectContaining({
|
223
|
+
namespace: 'ShowHideContent',
|
224
|
+
selector: 'input[type="radio"][name="single"]'
|
225
|
+
}))
|
226
|
+
expect(events && events.click).toContain(jasmine.objectContaining({
|
227
|
+
namespace: 'ShowHideContent',
|
228
|
+
selector: '[data-target] > input[type="checkbox"]'
|
229
|
+
}))
|
230
|
+
})
|
231
|
+
})
|
232
|
+
|
233
|
+
describe('and when this.showHideContent.destroy() is called', function () {
|
234
|
+
beforeEach(function () {
|
235
|
+
this.showHideContent.destroy()
|
236
|
+
})
|
237
|
+
|
238
|
+
it('should have no show/hide event handlers', function () {
|
239
|
+
var events = $._data(document.body, 'events')
|
240
|
+
expect(events && events.click).not.toContain(jasmine.objectContaining({
|
241
|
+
namespace: 'ShowHideContent',
|
242
|
+
selector: 'input[type="radio"][name="single"]'
|
243
|
+
}))
|
244
|
+
expect(events && events.click).not.toContain(jasmine.objectContaining({
|
245
|
+
namespace: 'ShowHideContent',
|
246
|
+
selector: '[data-target] > input[type="checkbox"]'
|
247
|
+
}))
|
248
|
+
})
|
249
|
+
})
|
250
|
+
})
|
251
|
+
|
252
|
+
describe('when the radios are outside of a form', function () {
|
253
|
+
beforeEach(function () {
|
254
|
+
// Sample markup
|
255
|
+
this.$content = $(
|
256
|
+
// Radio buttons (yes/no)
|
257
|
+
'<div class="multiple-choice" data-target="show-hide-radios">' +
|
258
|
+
'<input type="radio" name="single" value="yes">' +
|
259
|
+
'<label>Yes</label>' +
|
260
|
+
'</div>' +
|
261
|
+
'<div class="multiple-choice">' +
|
262
|
+
'<input type="radio" name="single" value="no">' +
|
263
|
+
'<label>No</label>' +
|
264
|
+
'</div>' +
|
265
|
+
'<div id="show-hide-radios" class="panel js-hidden" />'
|
266
|
+
)
|
267
|
+
|
268
|
+
// Find radios/checkboxes
|
269
|
+
var $radios = this.$content.find('input[type=radio]')
|
270
|
+
|
271
|
+
// Two radios
|
272
|
+
this.$radio1 = $radios.eq(0)
|
273
|
+
this.$radio2 = $radios.eq(1)
|
274
|
+
|
275
|
+
// Add to page
|
276
|
+
$(document.body).append(this.$content)
|
277
|
+
|
278
|
+
// Show/Hide content
|
279
|
+
this.$radioShowHide = $('#show-hide-radios')
|
280
|
+
|
281
|
+
// Add show/hide content support
|
282
|
+
this.showHideContent = new GOVUK.ShowHideContent()
|
283
|
+
this.showHideContent.init()
|
284
|
+
})
|
285
|
+
|
286
|
+
it('should make the show/hide content visible if its radio is checked', function () {
|
287
|
+
this.$radio1.click()
|
288
|
+
|
289
|
+
// Defaults changed, initialise again
|
290
|
+
this.showHideContent = new GOVUK.ShowHideContent().init()
|
291
|
+
expect(this.$radio1.attr('aria-expanded')).toBe('true')
|
292
|
+
expect(this.$radioShowHide.attr('aria-hidden')).toBe('false')
|
293
|
+
expect(this.$radioShowHide.hasClass('js-hidden')).toEqual(false)
|
294
|
+
})
|
295
|
+
|
296
|
+
it('should do nothing if a radio without show/hide content is checked', function () {
|
297
|
+
this.$radio2.click()
|
298
|
+
|
299
|
+
// Defaults changed, initialise again
|
300
|
+
this.showHideContent = new GOVUK.ShowHideContent().init()
|
301
|
+
expect(this.$radio1.attr('aria-expanded')).toBe('false')
|
302
|
+
expect(this.$radioShowHide.attr('aria-hidden')).toBe('true')
|
303
|
+
expect(this.$radioShowHide.hasClass('js-hidden')).toEqual(true)
|
304
|
+
})
|
305
|
+
})
|
306
|
+
})
|
@@ -0,0 +1,137 @@
|
|
1
|
+
/* global describe it expect beforeEach afterEach */
|
2
|
+
|
3
|
+
var $ = window.jQuery
|
4
|
+
|
5
|
+
describe('stick-at-top-when-scrolling', function () {
|
6
|
+
'use strict'
|
7
|
+
var GOVUK = window.GOVUK
|
8
|
+
|
9
|
+
var $stickyElement
|
10
|
+
var $stickyWrapper
|
11
|
+
|
12
|
+
beforeEach(function () {
|
13
|
+
$stickyElement = $('<div class="stick-at-top-when-scrolling"></div>')
|
14
|
+
$stickyWrapper = $('<div>').append($stickyElement)
|
15
|
+
|
16
|
+
$('body').append($stickyWrapper)
|
17
|
+
})
|
18
|
+
|
19
|
+
afterEach(function () {
|
20
|
+
$stickyWrapper.remove()
|
21
|
+
})
|
22
|
+
|
23
|
+
describe('when stick is called', function () {
|
24
|
+
it('should add fixed class on stick', function () {
|
25
|
+
expect(!$stickyElement.hasClass('content-fixed')).toBe(true)
|
26
|
+
GOVUK.stickAtTopWhenScrolling.stick($stickyElement)
|
27
|
+
expect($stickyElement.hasClass('content-fixed')).toBe(true)
|
28
|
+
})
|
29
|
+
|
30
|
+
it('should insert shim when sticking the element', function () {
|
31
|
+
expect($('.shim').length).toBe(0)
|
32
|
+
GOVUK.stickAtTopWhenScrolling.stick($stickyElement)
|
33
|
+
expect($('.shim').length).toBe(1)
|
34
|
+
})
|
35
|
+
|
36
|
+
it('should insert shim with minimum height', function () {
|
37
|
+
GOVUK.stickAtTopWhenScrolling.stick($stickyElement)
|
38
|
+
expect($('.shim').height()).toBe(1)
|
39
|
+
})
|
40
|
+
})
|
41
|
+
|
42
|
+
describe('when release is called', function () {
|
43
|
+
it('should remove fixed class', function () {
|
44
|
+
$stickyElement.addClass('content-fixed')
|
45
|
+
GOVUK.stickAtTopWhenScrolling.release($stickyElement)
|
46
|
+
expect($stickyElement.hasClass('content-fixed')).toBe(false)
|
47
|
+
})
|
48
|
+
|
49
|
+
it('should remove the shim', function () {
|
50
|
+
$stickyElement = $('<div class="stick-at-top-when-scrolling content-fixed"></div>')
|
51
|
+
GOVUK.stickAtTopWhenScrolling.release($stickyElement)
|
52
|
+
expect($('.shim').length).toBe(0)
|
53
|
+
})
|
54
|
+
})
|
55
|
+
|
56
|
+
describe('for larger screens (>768px)', function () {
|
57
|
+
beforeEach(function () {
|
58
|
+
GOVUK.stickAtTopWhenScrolling.getWindowPositions = function () {
|
59
|
+
return {
|
60
|
+
scrollTop: 300
|
61
|
+
}
|
62
|
+
}
|
63
|
+
GOVUK.stickAtTopWhenScrolling.getElementOffset = function () {
|
64
|
+
return {
|
65
|
+
top: 300
|
66
|
+
}
|
67
|
+
}
|
68
|
+
GOVUK.stickAtTopWhenScrolling.getWindowDimensions = function () {
|
69
|
+
return {
|
70
|
+
height: 768,
|
71
|
+
width: 769
|
72
|
+
}
|
73
|
+
}
|
74
|
+
GOVUK.stickAtTopWhenScrolling.$els = $stickyElement
|
75
|
+
GOVUK.stickAtTopWhenScrolling._hasScrolled = true
|
76
|
+
GOVUK.stickAtTopWhenScrolling.checkScroll()
|
77
|
+
})
|
78
|
+
|
79
|
+
it('should stick, if the scroll position is past the element position', function () {
|
80
|
+
expect($stickyElement.hasClass('content-fixed')).toBe(true)
|
81
|
+
})
|
82
|
+
|
83
|
+
it('should check the width of the parent, and make the width of the element and the shim the same on resize', function () {
|
84
|
+
var $stickyResizeElement = $('<div class="stick-at-top-when-scrolling js-sticky-resize"></div>')
|
85
|
+
var $stickyResizeWrapper = $('<div class="column-third" style="width:300px;">').append($stickyResizeElement)
|
86
|
+
$('body').append($stickyResizeWrapper)
|
87
|
+
|
88
|
+
GOVUK.stickAtTopWhenScrolling.$els = $stickyResizeElement
|
89
|
+
GOVUK.stickAtTopWhenScrolling._hasResized = true
|
90
|
+
GOVUK.stickAtTopWhenScrolling.checkResize()
|
91
|
+
|
92
|
+
var stickyElementParentWidth = $stickyResizeElement.parent('div').width()
|
93
|
+
expect(stickyElementParentWidth).toBe(300)
|
94
|
+
|
95
|
+
var stickyElementWidth = $stickyResizeElement.width()
|
96
|
+
expect(stickyElementWidth).toBe(300)
|
97
|
+
|
98
|
+
var stickElementShimWidth = $('.shim').width()
|
99
|
+
expect(stickElementShimWidth).toBe(300)
|
100
|
+
})
|
101
|
+
|
102
|
+
it('should unstick, if the scroll position is less than the point at which scrolling started', function () {
|
103
|
+
GOVUK.stickAtTopWhenScrolling.getWindowPositions = function () {
|
104
|
+
return {
|
105
|
+
scrollTop: 0
|
106
|
+
}
|
107
|
+
}
|
108
|
+
GOVUK.stickAtTopWhenScrolling.$els = $stickyElement
|
109
|
+
GOVUK.stickAtTopWhenScrolling._hasScrolled = true
|
110
|
+
GOVUK.stickAtTopWhenScrolling.checkScroll()
|
111
|
+
expect($stickyElement.hasClass('content-fixed')).toBe(false)
|
112
|
+
})
|
113
|
+
})
|
114
|
+
|
115
|
+
describe('for smaller screens (<=768px)', function () {
|
116
|
+
beforeEach(function () {
|
117
|
+
GOVUK.stickAtTopWhenScrolling.getWindowDimensions = function () {
|
118
|
+
return {
|
119
|
+
height: 768,
|
120
|
+
width: 767
|
121
|
+
}
|
122
|
+
}
|
123
|
+
GOVUK.stickAtTopWhenScrolling.getElementOffset = function () {
|
124
|
+
return {
|
125
|
+
top: 300
|
126
|
+
}
|
127
|
+
}
|
128
|
+
GOVUK.stickAtTopWhenScrolling.$els = $stickyElement
|
129
|
+
GOVUK.stickAtTopWhenScrolling._hasScrolled = true
|
130
|
+
GOVUK.stickAtTopWhenScrolling.checkScroll()
|
131
|
+
})
|
132
|
+
|
133
|
+
it('should unstick the element', function () {
|
134
|
+
expect($stickyElement.hasClass('content-fixed')).toBe(false)
|
135
|
+
})
|
136
|
+
})
|
137
|
+
})
|
File without changes
|
@@ -0,0 +1,81 @@
|
|
1
|
+
// Media query helpers. These make producing IE layouts
|
2
|
+
// super easy.
|
3
|
+
|
4
|
+
// The base css you write should be for mobile. You can
|
5
|
+
// then add desktop styles on top.
|
6
|
+
//
|
7
|
+
// Usage:
|
8
|
+
//
|
9
|
+
// div.columns {
|
10
|
+
// border: 1px solid;
|
11
|
+
//
|
12
|
+
// @include media(desktop){
|
13
|
+
// width: 30%;
|
14
|
+
// float: left;
|
15
|
+
// }
|
16
|
+
// @include ie-lte(8) {
|
17
|
+
// something to fix visual bugs in old IE
|
18
|
+
// }
|
19
|
+
// @include ie(6) {
|
20
|
+
// padding: 0;
|
21
|
+
// }
|
22
|
+
// }
|
23
|
+
|
24
|
+
|
25
|
+
$is-ie: false !default;
|
26
|
+
$mobile-ie6: true !default;
|
27
|
+
|
28
|
+
$tablet-breakpoint: 641px !default;
|
29
|
+
$desktop-breakpoint: 769px !default;
|
30
|
+
|
31
|
+
@mixin media($size: false, $max-width: false, $min-width: false, $ignore-for-ie: false) {
|
32
|
+
@if $is-ie and ($ignore-for-ie == false) {
|
33
|
+
@if $size != mobile {
|
34
|
+
@if ($ie-version == 6 and $mobile-ie6 == false) or $ie-version > 6 {
|
35
|
+
@content;
|
36
|
+
}
|
37
|
+
}
|
38
|
+
} @else {
|
39
|
+
@if $size == desktop {
|
40
|
+
@media (min-width: $desktop-breakpoint){
|
41
|
+
@content;
|
42
|
+
}
|
43
|
+
} @else if $size == tablet {
|
44
|
+
@media (min-width: $tablet-breakpoint){
|
45
|
+
@content;
|
46
|
+
}
|
47
|
+
} @else if $size == mobile {
|
48
|
+
@media (max-width: $tablet-breakpoint - 1px){
|
49
|
+
@content;
|
50
|
+
}
|
51
|
+
} @else if $max-width != false {
|
52
|
+
@media (max-width: $max-width){
|
53
|
+
@content;
|
54
|
+
}
|
55
|
+
} @else if $min-width != false {
|
56
|
+
@media (min-width: $min-width){
|
57
|
+
@content;
|
58
|
+
}
|
59
|
+
} @else {
|
60
|
+
@media (min-width: $size){
|
61
|
+
@content
|
62
|
+
}
|
63
|
+
}
|
64
|
+
}
|
65
|
+
}
|
66
|
+
|
67
|
+
@mixin ie-lte($version) {
|
68
|
+
@if $is-ie {
|
69
|
+
@if $ie-version <= $version {
|
70
|
+
@content;
|
71
|
+
}
|
72
|
+
}
|
73
|
+
}
|
74
|
+
|
75
|
+
@mixin ie($version) {
|
76
|
+
@if $is-ie {
|
77
|
+
@if $ie-version == $version {
|
78
|
+
@content;
|
79
|
+
}
|
80
|
+
}
|
81
|
+
}
|
@@ -0,0 +1,90 @@
|
|
1
|
+
// CSS 3 mixins
|
2
|
+
|
3
|
+
// This file includes mixins for CSS properties that require vendor prefixes.
|
4
|
+
|
5
|
+
// Please add more mixins here as you need them, rather than adding them to
|
6
|
+
// your application - this lets us manage them in one place.
|
7
|
+
|
8
|
+
// You can use the @warn directive to deprecate a mixin where the property
|
9
|
+
// no longer needs prefixes.
|
10
|
+
|
11
|
+
// This style of indentation is preferred as it is easier to scan
|
12
|
+
// Allow more than two spaces per indentation level and don't require a space after a colon
|
13
|
+
// scss-lint:disable Indentation SpaceAfterPropertyColon
|
14
|
+
|
15
|
+
@mixin border-radius($radius) {
|
16
|
+
-webkit-border-radius: $radius; // Chrome 4.0, Safari 3.1 to 4.0, Mobile Safari 3.2, Android Browser 2.1
|
17
|
+
-moz-border-radius: $radius; // Firefox 2.0 to 3.6
|
18
|
+
border-radius: $radius;
|
19
|
+
}
|
20
|
+
|
21
|
+
@mixin box-shadow($shadow) {
|
22
|
+
-webkit-box-shadow: $shadow; // Chrome 4.0 to 9.0, Safari 3.1 to 5.0, Mobile Safari 3.2 to 4.3, Android Browser 2.1 to 3.0
|
23
|
+
-moz-box-shadow: $shadow; // Firefox 3.5 to 3.6
|
24
|
+
box-shadow: $shadow;
|
25
|
+
}
|
26
|
+
|
27
|
+
@mixin scale($x, $y, $transform-origin: 50% 50% 0) {
|
28
|
+
// $x and $y should be numeric values without units
|
29
|
+
-webkit-transform: scale($x, $y); // Still in use now, started at: Chrome 4.0, Safari 3.1, Mobile Safari 3.2, Android 2.1
|
30
|
+
-moz-transform: scale($x, $y); // Firefox 3.5 to 15.0
|
31
|
+
-ms-transform: scale($x, $y); // IE9 only
|
32
|
+
transform: scale($x, $y);
|
33
|
+
|
34
|
+
-webkit-transform-origin: $transform-origin; // Chrome, Safari 3.1
|
35
|
+
-moz-transform-origin: $transform-origin; // Firefox 10 to 15.0
|
36
|
+
-ms-transform-origin: $transform-origin; // IE9
|
37
|
+
transform-origin: $transform-origin;
|
38
|
+
}
|
39
|
+
|
40
|
+
@mixin translate($x, $y) {
|
41
|
+
-webkit-transform: translate($x, $y); // Still in use now, started at: Chrome 4.0, Safari 3.1, Mobile Safari 3.2, Android 2.1
|
42
|
+
-moz-transform: translate($x, $y); // Firefox 3.5 to 15.0
|
43
|
+
-ms-transform: translate($x, $y); // IE9 only
|
44
|
+
-o-transform: translate($x, $y); // Opera 10.5 to 12.0
|
45
|
+
transform: translate($x, $y);
|
46
|
+
}
|
47
|
+
|
48
|
+
@mixin gradient($from, $to) {
|
49
|
+
// Creates a vertical gradient where $from is the colour at the top of the element
|
50
|
+
// and $to is the colour at the bottom. The top colour is used as a background-color
|
51
|
+
// for browsers that don't support gradients.
|
52
|
+
background-color: $from;
|
53
|
+
background-image: -webkit-gradient(linear, 0% 0%, 0% 100%, from($from), to($to)); // Safari 4.0 to 5.1, Chrome 1.0 to 10.0, old deprecated syntax
|
54
|
+
background-image: -webkit-linear-gradient($from, $to); // Chrome 10.0 to 25.0, Safari 5.1 to 6.0, Mobile Safari 5.0 to 6.1, Android Browser 4.0 to 4.3
|
55
|
+
background-image: -moz-linear-gradient($from, $to); // Firefox 3.6 to 15.0
|
56
|
+
background-image: -o-linear-gradient($from, $to); // Opera 11.1 to 12.0
|
57
|
+
background-image: linear-gradient($from, $to);
|
58
|
+
filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#{$from}', endColorstr='#{$to}',GradientType=0 ); // IE6 to IE9
|
59
|
+
}
|
60
|
+
|
61
|
+
@mixin transition($property, $duration, $function, $delay: 0s) {
|
62
|
+
-webkit-transition: ($property $duration $function $delay); // Chrome 4.0 to 25.0, Safari 3.1 to 6.0, Mobile Safari 3.2 to 6.1, Android Browser 2.1 to 4.3
|
63
|
+
-moz-transition: ($property $duration $function $delay); // Firefox 4.0 to 15.0
|
64
|
+
-o-transition: ($property $duration $function $delay); // Opera 10.5 to 12.0
|
65
|
+
transition: ($property $duration $function $delay);
|
66
|
+
}
|
67
|
+
|
68
|
+
@mixin box-sizing($type) {
|
69
|
+
// http://www.w3.org/TR/css3-ui/#box-sizing
|
70
|
+
// $type can be one of: content-box | padding-box | border-box | inherit
|
71
|
+
-webkit-box-sizing: $type; // Chrome 4.0 to 9.0, Safari 3.1 to 5.0, Mobile Safari 3.2 to 4.3, Android Browser 2.1 to 3.0
|
72
|
+
-moz-box-sizing: $type; // Firefox 2.0 to 28.0, Firefox for Android 26.0 onwards
|
73
|
+
box-sizing: $type;
|
74
|
+
}
|
75
|
+
|
76
|
+
@mixin appearance($appearance) {
|
77
|
+
-webkit-appearance: $appearance;
|
78
|
+
-moz-appearance: $appearance;
|
79
|
+
}
|
80
|
+
|
81
|
+
@mixin calc($property, $calc) {
|
82
|
+
#{$property}: -webkit-calc(#{$calc}); // Chrome 19.0 to 25.0, Safari 6.0, Mobile Safari 6.0 to 6.1
|
83
|
+
#{$property}: calc(#{$calc});
|
84
|
+
}
|
85
|
+
|
86
|
+
@mixin opacity($trans) {
|
87
|
+
zoom: 1;
|
88
|
+
filter: unquote('alpha(opacity=' + ($trans * 100) + ')'); // IE6 to IE8
|
89
|
+
opacity: $trans;
|
90
|
+
}
|
@@ -0,0 +1,10 @@
|
|
1
|
+
@mixin device-pixel-ratio($ratio: 2) {
|
2
|
+
@media only screen and (-webkit-min-device-pixel-ratio: $ratio),
|
3
|
+
only screen and (min--moz-device-pixel-ratio: $ratio),
|
4
|
+
only screen and ( -o-min-device-pixel-ratio: #{($ratio*10)}/10),
|
5
|
+
only screen and ( min-device-pixel-ratio: $ratio),
|
6
|
+
only screen and ( min-resolution: #{($ratio*96)}dpi),
|
7
|
+
only screen and ( min-resolution: #{$ratio}dppx) {
|
8
|
+
@content;
|
9
|
+
}
|
10
|
+
}
|