diff --git a/ghost/admin/assets/sass/modules/breakpoint.scss b/ghost/admin/assets/sass/modules/breakpoint.scss index 1415b5722d..cb6a9dfa69 100644 --- a/ghost/admin/assets/sass/modules/breakpoint.scss +++ b/ghost/admin/assets/sass/modules/breakpoint.scss @@ -1,6 +1,6 @@ /* - * Breakpoint Sass 1.3.0 - * Last updated: 2012-08-28 + * Breakpoint Sass 2.0.6 + * Last updated: July 2013 * Copyright: Mason Wendell 2012 - MIT Licensed * Source: https://github.com/canarymason/breakpoint */ @@ -8,302 +8,137 @@ ////////////////////////////// // Default Variables ////////////////////////////// -$breakpoint-default-feature: 'min-width' !default; -$breakpoint-default-media: 'all' !default; -$breakpoint-force-media-all: false !default; -$breakpoint-default-pair: 'width' !default; -$breakpoint-to-ems: false !default; -$breakpoint-prefixes: 'webkit' 'moz' !default; -$breakpoint-prefixed-queries: 'device-pixel-ratio' 'min-device-pixel-ratio' 'max-device-pixel-ratio' !default; +// Default Features +$breakpoint-default-media: all !default; +$breakpoint-default-feature: min-width !default; +$breakpoint-default-pair: width !default; -$breakpoint-no-queries: false !default; -$breakpoint-no-query-wrappers: false !default; +// Default Transforms +$breakpoint-force-media-all: false !default; +$breakpoint-to-ems: false !default; +$breakpoint-resolutions: true !default; -$breakpoint-base-font-size: false; +// Default No Query Options +$breakpoint-no-queries: false !default; +$breakpoint-no-query-fallbacks: false !default; + +// Deftault Base Font Size +$breakpoint-base-font-size: 16px !default; + +// Legacy Syntax Support +$breakpoint-legacy-syntax: false !default; ////////////////////////////// -// Converts the input value to Base EMs +// Imports ////////////////////////////// -@function breakpoint-to-base-em($value, $base-font-size: false) { - $value-unit: unit($value); +@import 'breakpoint/context'; +@import 'breakpoint/helpers'; +@import 'breakpoint/parsers'; +@import 'breakpoint/no-query'; - // Will convert relative EMs into root EMs. - @if $base-font-size and type-of($base-font-size) == 'number' and $value-unit == 'em' { - $base-unit: unit($base-font-size); - - @if $base-unit == 'px' or $base-unit == '%' or $base-unit == 'em' or $base-unit == 'pt' { - @return base-conversion($value) / base-conversion($base-font-size) * 1em; - } - @else { - @warn '#{$base-font-size} is not set in valid units for font size!'; - @return false; - } - } - @else { - @return base-conversion($value); - } -} - -@function base-conversion($value) { - $unit: unit($value); - - @if $unit == 'px' { - @return $value / 16px * 1em; - } - @else if $unit == '%' { - @return $value / 100% * 1em; - } - @else if $unit == 'em' { - @return $value; - } - @else if $unit == 'pt' { - @return $value / 12pt * 1em; - } - @else { - @return $value; -// @warn 'Everything is terrible! What have you done?!'; - } -} - -////////////////////////////// -// Returns whether the feature can have a min/max pair -////////////////////////////// -@function breakpoint-min-max($feature) { - @if $feature == 'color' or $feature == 'color-index' or $feature == 'aspect-ratio' or $feature == 'device-height' or $feature == 'device-width' or $feature == 'height' or $feature == 'monochrome' or $feature == 'resolution' or $feature == 'width' or $feature == 'device-pixel-ratio' { - @return true; - } - @else { - @return false; - } -} - -////////////////////////////// -// Returns whether the feature can have a string value -////////////////////////////// -@function breakpoint-string-value($feature) { -@if $feature == 'orientation' or $feature == 'scan' or $feature == 'color' or $feature == 'resolution' or $feature == 'min-resolution' or $feature == 'max-resolution' { - @return true; - } - @else { - @return false; - } -} - -////////////////////////////// -// Experimental Media Queries -////////////////////////////// -@function breakpoint-experimental($property, $prefix) { - @if $property == 'min-device-pixel-ratio' { - @if $prefix == 'webkit' { - @return '-#{$prefix}-#{$property}'; - } - @else if $prefix == 'moz' { - @return 'min--#{$prefix}-device-pixel-ratio'; - } - @else { - @warn '#{$property} is not fully supported in -#{prefix}'; - @return 'ERROR'; - } - } - @else if $property == 'max-device-pixel-ratio' { - @if $prefix == 'webkit' { - @return '-#{$prefix}-#{$property}'; - } - @else if $prefix == 'moz' { - @return 'max--#{$prefix}-device-pixel-ratio'; - } - @else { - @warn '#{$property} is not fully supported in -#{prefix}'; - @return 'ERROR'; - } - } - @else { - @return '-#{$prefix}-#{$property}'; - } -} - - -////////////////////////////// -// Private Breakpoint Variables -////////////////////////////// -$TXkgdmFyaWFibGUhIEdvIGF3YXkh: () !default; - -////////////////////////////// -// Breakpoint Get Context -// $feature: Input feature to get it's current MQ context. Returns false if no context -////////////////////////////// -@function breakpoint-get-context($feature) { - @each $context in $TXkgdmFyaWFibGUhIEdvIGF3YXkh { - @if $feature == nth($context, 1) { - @return nth($context, 2); - } - } - - @return false; -} - -////////////////////////////// -// Private function to set context -////////////////////////////// -@function U2V0IHlvdXIgb3duIGRhbW4gY29udGV4dHMh($feature, $value) { - @if $value == 'monochrome' { - $feature: 'monochrome'; - } - - $append: $feature; - $append: join($append, $value, space); - - $TXkgdmFyaWFibGUhIEdvIGF3YXkh: append($TXkgdmFyaWFibGUhIEdvIGF3YXkh, $append, comma); - - @return true; -} - -////////////////////////////// -// Private function to reset context -////////////////////////////// -@mixin TXkgcmVzZXQhIEdvIGF3YXkh { - $TXkgdmFyaWFibGUhIEdvIGF3YXkh: (); -} +@import 'breakpoint/respond-to'; ////////////////////////////// // Breakpoint Mixin ////////////////////////////// -@mixin breakpoint($breakpoint, $media: $breakpoint-default-media, $no-query: false, $base-font-size: $breakpoint-base-font-size) { - // Query and Media String Defaults - $query: false !default; - $query-holder: false !default; - $media-string: false !default; - $do-prefix: false !default; - $webkit: false !default; - $webkit-first: true !default; - $moz: false !default; - $moz-first: true !default; - $o: false !default; - $o-first: true !default; - $ms: false !default; - $ms-first: true !default; +@mixin breakpoint($query, $no-query: false) { + // Internal Variables + $query-string: ''; - // Holder for Count - $first: true !default; + // Reset contexts + @include private-breakpoint-reset-contexts(); - // Reset Context - @include TXkgcmVzZXQhIEdvIGF3YXkh; + // Test to see if it's a comma-separated list + $or-list: is-breakpoint-list($query); + $query-fallback: false; - // Set Media Context - $context: U2V0IHlvdXIgb3duIGRhbW4gY29udGV4dHMh('media', $media); - // Initialize Query String - @if $media != 'all' or $breakpoint-force-media-all { - $media-string: "#{$media} "; - } - @else { - $media-string: ""; - } + @if ($or-list != false and $breakpoint-legacy-syntax == false) { + $length: length($query); - // If we have a single query, let's just work with that. - @if is_breakpoint_list($breakpoint) == false { - @each $prefix-query in $breakpoint-prefixed-queries { - @if $do-prefix == false { - $do-prefix: featureExists($prefix-query, $breakpoint); - } + $last: nth($query, $length); + $query-fallback: breakpoint-no-query($last); + + @if ($query-fallback != false) { + $length: $length - 1; } - @if $do-prefix { - @each $prfx in $breakpoint-prefixes { - @if $prfx == 'webkit' { - $webkit: breakpoint-switch($breakpoint, $media-string, true, $prfx, $base-font-size: $base-font-size); - } - @if $prfx == 'moz' { - $moz: breakpoint-switch($breakpoint, $media-string, true, $prfx, $base-font-size: $base-font-size); - } - @if $prfx == 'o' { - $o: breakpoint-switch($breakpoint, $media-string, true, $prfx, $base-font-size: $base-font-size); - } - - @if $prfx == 'ms' { - $ms: breakpoint-switch($breakpoint, $media-string, true, $prfx, $base-font-size: $base-font-size); - } + @for $i from 1 through $length { + @if $i == 1 { + $query-string: breakpoint-parse(nth($query, $i)); + } + @else { + $query-string: $query-string + ', ' + breakpoint-parse(nth($query, $i)); } - } - @else { - $query: breakpoint-switch($breakpoint, $media-string, true, $base-font-size: $base-font-size); } } @else { - // See if Prefix Query exists - @each $prefix-query in $breakpoint-prefixed-queries { - @if $do-prefix == false { - $do-prefix: featureExists($prefix-query, $breakpoint); + @if ($breakpoint-legacy-syntax == true) { + $length: length($query); + + $last: nth($query, $length); + $query-fallback: breakpoint-no-query($last); + + @if ($query-fallback != false) { + $length: $length - 1; } - } - @if $do-prefix { - @each $prfx in $breakpoint-prefixes { - @each $bkpt in $breakpoint { - @if $prfx == 'webkit' { - @if $webkit-first { - $webkit: breakpoint-switch($bkpt, $media-string, true, $prfx, $base-font-size: $base-font-size); - $webkit-first: false; - } - @else { - $webkit: join($webkit, breakpoint-switch($bkpt, $media-string, $prefix: $prfx, $base-font-size: $base-font-size)); - } - } + $mq: (); - @if $prfx == 'moz' { - @if $moz-first { - $moz: breakpoint-switch($bkpt, $media-string, true, $prfx, $base-font-size: $base-font-size); - $moz-first: false; - } - @else { - $moz: join($moz, breakpoint-switch($bkpt, $media-string, $prefix: $prfx, $base-font-size: $base-font-size)); - } - } - - @if $prfx == 'o' { - @if $o-first { - $o: breakpoint-switch($bkpt, $media-string, true, $prfx, $base-font-size: $base-font-size); - $o-first: false; - } - @else { - $o: join($o, breakpoint-switch($bkpt, $media-string, $prefix: $prfx, $base-font-size: $base-font-size)); - } - } - - @if $prfx == 'ms' { - @if $ms-first { - $ms: breakpoint-switch($bkpt, $media-string, true, $prfx, $base-font-size: $base-font-size); - $ms-first: false; - } - @else { - $ms: join($ms, breakpoint-switch($bkpt, $media-string, $prefix: $prfx, $base-font-size: $base-font-size)); - } - } - } + @for $i from 1 through $length { + $mq: append($mq, nth($query, $i), comma); } + + $query-string: breakpoint-parse($mq); } @else { - @each $bkpt in $breakpoint { - @if $first == true { - $query: breakpoint-switch($bkpt, $media-string, true, $base-font-size: $base-font-size); - $first: false; - } - @else { - $query: join($query, breakpoint-switch($bkpt, $media-string, $base-font-size: $base-font-size)); - } - } + $query-string: breakpoint-parse($query); } } - @if $breakpoint-no-queries { - @if $no-query { - $context: U2V0IHlvdXIgb3duIGRhbW4gY29udGV4dHMh('no queries', true); - @if $breakpoint-no-query-wrappers and type-of($no-query) == string { - #{$no-query} & { + // Allow for an as-needed override or usage of no query fallback. + @if $no-query != false { + $query-fallback: $no-query; + } + + + // Print Out Query String + @if not $breakpoint-no-queries { + @media #{$query-string} { + @content; + } + } + + @if $breakpoint-no-query-fallbacks != false { + + $type: type-of($breakpoint-no-query-fallbacks); + $print: false; + + @if ($type == 'bool') { + $print: true; + } + @else if ($type == 'string') { + @if $query-fallback == $breakpoint-no-query-fallbacks { + $print: true; + } + } + @else if ($type == 'list') { + @each $wrapper in $breakpoint-no-query-fallbacks { + @if $query-fallback == $wrapper { + $print: true; + } + } + } + + // Write Fallback + @if ($query-fallback != false) and ($print == true) { + $type-fallback: type-of($query-fallback); + + @if ($type-fallback != 'bool') { + #{$query-fallback} & { @content; - $context: U2V0IHlvdXIgb3duIGRhbW4gY29udGV4dHMh('no query wrapper', $no-query); } } @else { @@ -311,236 +146,6 @@ $TXkgdmFyaWFibGUhIEdvIGF3YXkh: () !default; } } } - @else { - @if $breakpoint-no-query-wrappers and type-of($no-query) == string { - #{$no-query} & { - @content; - $context: U2V0IHlvdXIgb3duIGRhbW4gY29udGV4dHMh('no query wrapper', $no-query); - } - } - @if $query { - @media #{$query} { - @content; - } - } - @else { - $pf-queries: $webkit, $moz, $o, $ms; - $pf-query: (); - @each $pfq in $pf-queries { - @if $pfq { - $pf-query: append($pf-query, $pfq, comma); - } - } - @media #{$pf-query} { - @content; - } - } - } - - @include TXkgcmVzZXQhIEdvIGF3YXkh; + @include private-breakpoint-reset-contexts(); } - -@function breakpoint-switch($breakpoint, $media-string, $first: false, $prefix: false, $base-font-size: $breakpoint-base-font-size) { - // Feature/Value/Length/Query Placehoders: - $feature: false !default; - $min-feature: "min-#{$breakpoint-default-pair}" !default; - $max-feature: "max-#{$breakpoint-default-pair}" !default; - $value: false !default; - $min-value: false !default; - $max-value: false !default; - $length: false !default; - $query: false !default; - - $length: length($breakpoint); - // Check to see if there is only one item. - @if $length == 1 { - $value: $breakpoint; - @if type-of($breakpoint) == 'number' { - $feature: $breakpoint-default-feature; - } - - // If EM Breakpoints are active, do it! - @if $breakpoint-to-ems and type-of($value) == 'number' { - $value: breakpoint-to-base-em($value, $base-font-size); - } - // Build the Query - $query: breakpoint-generate($media-string, $feature, $value, $first); - // Set Context - $context: U2V0IHlvdXIgb3duIGRhbW4gY29udGV4dHMh($feature, $value); - } - @else if $length == 2 { - // If both are numbers, we've got a double! - @if type-of(nth($breakpoint, 1)) == 'number' and type-of(nth($breakpoint, 2)) == 'number' { - // See which is larger. - @if nth($breakpoint, 1) > nth($breakpoint, 2) { - $min-value: nth($breakpoint, 2); - $max-value: nth($breakpoint, 1); - } - @else { - $min-value: nth($breakpoint, 1); - $max-value: nth($breakpoint, 2); - } - - // If EM Breakpoints are active, do it! - @if $breakpoint-to-ems and type-of($min-value) == 'number' { - $min-value: breakpoint-to-base-em($min-value, $base-font-size); - } - @if $breakpoint-to-ems and type-of($max-value) == 'number' { - $max-value: breakpoint-to-base-em($max-value, $base-font-size); - } - - // Min/Max for given - $query: breakpoint-generate($media-string, $min-feature, $min-value, $first); - $query: join($query, breakpoint-generate($media-string, $max-feature, $max-value)); - // Set Context - $context: U2V0IHlvdXIgb3duIGRhbW4gY29udGV4dHMh($min-feature, $min-value); - $context: U2V0IHlvdXIgb3duIGRhbW4gY29udGV4dHMh($max-feature, $max-value); - } - @else if type-of(nth($breakpoint, 1)) == 'string' and type-of(nth($breakpoint, 2)) == 'string' { - @if breakpoint-string-value(nth($breakpoint, 1)) == true { - $feature: nth($breakpoint, 1); - $value: nth($breakpoint, 2); - } - @else { - $feature: nth($breakpoint, 2); - $value: nth($breakpoint, 1); - } - - // If EM Breakpoints are active, do it! - @if $breakpoint-to-ems and type-of($value) == 'number' { - $value: breakpoint-to-base-em($value, $base-font-size); - } - - // Build the Query - $query: breakpoint-generate($media-string, $feature, $value, $first); - // Set Context - $context: U2V0IHlvdXIgb3duIGRhbW4gY29udGV4dHMh($feature, $value); - } - @else { - // Because we can have either the first or second option be the feature, we switch on it. - @if type-of(nth($breakpoint, 1)) == string { - $feature: nth($breakpoint, 1); - $value: nth($breakpoint, 2); - } - @else if type-of(nth($breakpoint, 2)) == string { - $feature: nth($breakpoint, 2); - $value: nth($breakpoint, 1); - } - - @if $feature == 'device-pixel-ratio' or $feature == 'min-device-pixel-ratio' or $feature == 'max-device-pixel-ratio' { - $feature: breakpoint-experimental($feature, $prefix); - //$value: 96 * $value * 1dpi; - // @if $feature == 'device-pixel-ratio' { - // $feature: 'resolution'; - // } - // @else if $feature == 'min-device-pixel-ratio' { - // $feature: 'min-resolution'; - // } - // @else if $feature == 'max-device-pixel-ratio' { - // $feature: 'max-resolution'; - // } - } - - // If EM Breakpoints are active, do it! - @if $breakpoint-to-ems and type-of($value) == 'number' { - $value: breakpoint-to-base-em($value, $base-font-size); - } - - // Build the Query - $query: breakpoint-generate($media-string, $feature, $value, $first); - // Set Context - $context: U2V0IHlvdXIgb3duIGRhbW4gY29udGV4dHMh($feature, $value); - } - } - @else if $length == 3 { - @if type-of(nth($breakpoint, 1)) == 'string' { - $feature: nth($breakpoint, 1); - // See which is larger. - @if nth($breakpoint, 2) > nth($breakpoint, 3) { - $min-value: nth($breakpoint, 3); - $max-value: nth($breakpoint, 2); - } - @else { - $min-value: nth($breakpoint, 2); - $max-value: nth($breakpoint, 3); - } - } - @else { - $feature: nth($breakpoint, 3); - // See which is larger. - @if nth($breakpoint, 1) > nth($breakpoint, 2) { - $min-value: nth($breakpoint, 2); - $max-value: nth($breakpoint, 1); - } - @else { - $min-value: nth($breakpoint, 1); - $max-value: nth($breakpoint, 2); - } - } - - // If EM Breakpoints are active, do it! - @if $breakpoint-to-ems and type-of($min-value) == 'number' { - $min-value: breakpoint-to-base-em($min-value, $base-font-size); - } - @if $breakpoint-to-ems and type-of($max-value) == 'number' { - $max-value: breakpoint-to-base-em($max-value, $base-font-size); - } - - @if breakpoint-min-max($feature) == true { - @if $feature == 'device-pixel-ratio' { - $min-feature: breakpoint-experimental('min-#{$feature}', $prefix); - $max-feature: breakpoint-experimental('max-#{$feature}', $prefix); - } - @else { - $min-feature: 'min-#{$feature}'; - $max-feature: 'max-#{$feature}'; - } - - // Min/Max for given - $query: breakpoint-generate($media-string, $min-feature, $min-value, $first); - $query: join($query, breakpoint-generate($media-string, $max-feature, $max-value)); - // Set Context - $context: U2V0IHlvdXIgb3duIGRhbW4gY29udGV4dHMh($min-feature, $min-value); - $context: U2V0IHlvdXIgb3duIGRhbW4gY29udGV4dHMh($max-feature, $max-value); - } - @else { - @warn '#{$feature} cannot have a min/max value!'; - } - } - - @return $query; -} - -@function breakpoint-generate($media, $feature, $value, $first: false) { - // Media Query string to be returned - $new-string: ""; - - // If it's the first item, it gets special treatment - @if $first == true { - // And Statement - $and: 'and '; - // If $media is blank (i.e. all), remove and statement - @if $media == '' { - $and: ''; - } - - @if $feature != false { - $new-string: #{$media}unquote("#{$and}(#{$feature}: #{$value})"); - } - @else { - $new-string: #{$media}unquote("#{$and}(#{$value})"); - } - } - - @else { - @if $feature != false { - $new-string: unquote("and (#{$feature}: #{$value})"); - } - @else { - $new-string: unquote("and (#{$value})"); - } - } - - @return $new-string; -} \ No newline at end of file diff --git a/ghost/admin/assets/sass/modules/breakpoint/_context.scss b/ghost/admin/assets/sass/modules/breakpoint/_context.scss new file mode 100755 index 0000000000..cf645257ce --- /dev/null +++ b/ghost/admin/assets/sass/modules/breakpoint/_context.scss @@ -0,0 +1,133 @@ +////////////////////////////// +// Private Breakpoint Variables +////////////////////////////// +$private-breakpoint-context-holder: (); +$private-breakpoint-context-placeholder: 0; + +////////////////////////////// +// Breakpoint Has Context +// Returns whether or not you are inside a Breakpoint query +////////////////////////////// +@function breakpoint-has-context() { + @if length($private-breakpoint-context-placeholder) { + @return true; + } + @else { + @return false; + } +} + + +////////////////////////////// +// Breakpoint Get Context +// $feature: Input feature to get it's current MQ context. Returns false if no context +////////////////////////////// +@function breakpoint-get-context($feature) { + @each $context in $private-breakpoint-context-holder { + @if $feature == nth($context, 1) { + // strip feature name + $values: (); + @for $i from 2 through length($context) { + $values: append($values, nth($context, $i), comma); + } + + $length: length($values) + 1; + @for $i from $length through $private-breakpoint-context-placeholder { + // Apply the Default Media type if feature is media + @if $feature == 'media' { + $values: append($values, $breakpoint-default-media, comma); + } + @else { + $values: append($values, false, comma); + } + } + + @return $values; + } + } + + @return false; +} + +////////////////////////////// +// Private function to set context +////////////////////////////// +@function private-breakpoint-set-context($feature, $value) { + @if $value == 'monochrome' { + $feature: 'monochrome'; + } + + $placeholder-plus-one: ($private-breakpoint-context-placeholder + 1); + + $holder: (); + + @if $private-breakpoint-context-placeholder == 1 { + $holder: ($feature $value); + $private-breakpoint-context-holder: append($private-breakpoint-context-holder, $holder, comma); + @return true; + + } @else { + $feature-used: false; + @each $context in $private-breakpoint-context-holder { + @if nth($context, 1) == $feature { + $feature-used: $context; + } + } + + @if $feature-used != false { + $holder: $feature; + @for $i from 2 through $placeholder-plus-one { + @if $i <= length($feature-used) { + $holder: append($holder, nth($feature-used, $i), space); + } @elseif $i < $placeholder-plus-one { + $holder: append($holder, false, space); + } @else { + $holder: append($holder, $value, space); + } + } + } + @elseif $feature-used == false { + $holder: $feature; + @for $i from 2 through $placeholder-plus-one { + @if $i < $placeholder-plus-one { + // Apply the Default Media type if feature is media + @if $feature == 'media' { + $holder: append($holder, $breakpoint-default-media, space); + } + @else { + $holder: append($holder, false, space); + } + + } @else { + $holder: append($holder, $value, space); + } + } + } + + // Rebuild context + $rebuild: (); + @if $feature-used != false { + @each $context in $private-breakpoint-context-holder { + @if nth($context, 1) == nth($holder, 1) { + $rebuild: append($rebuild, $holder, comma); + } @else { + $rebuild: append($rebuild, $context, comma); + } + } + + } @else { + $rebuild: append($private-breakpoint-context-holder, $holder, comma); + } + $private-breakpoint-context-holder: $rebuild; + } + + @return true; +} + +////////////////////////////// +// Private function to reset context +////////////////////////////// +@mixin private-breakpoint-reset-contexts { + $private-breakpoint-context-holder: (); + $private-breakpoint-context-placeholder: 0; +} diff --git a/ghost/admin/assets/sass/modules/breakpoint/_helpers.scss b/ghost/admin/assets/sass/modules/breakpoint/_helpers.scss new file mode 100755 index 0000000000..7a3dede620 --- /dev/null +++ b/ghost/admin/assets/sass/modules/breakpoint/_helpers.scss @@ -0,0 +1,151 @@ +////////////////////////////// +// Converts the input value to Base EMs +////////////////////////////// +@function breakpoint-to-base-em($value) { + $value-unit: unit($value); + + // Will convert relative EMs into root EMs. + @if $breakpoint-base-font-size and type-of($breakpoint-base-font-size) == 'number' and $value-unit == 'em' { + $base-unit: unit($breakpoint-base-font-size); + + @if $base-unit == 'px' or $base-unit == '%' or $base-unit == 'em' or $base-unit == 'pt' { + @return base-conversion($value) / base-conversion($breakpoint-base-font-size) * 1em; + } + @else { + @warn '#{$breakpoint-base-font-size} is not set in valid units for font size!'; + @return false; + } + } + @else { + @return base-conversion($value); + } +} + +@function base-conversion($value) { + $unit: unit($value); + + @if $unit == 'px' { + @return $value / 16px * 1em; + } + @else if $unit == '%' { + @return $value / 100% * 1em; + } + @else if $unit == 'em' { + @return $value; + } + @else if $unit == 'pt' { + @return $value / 12pt * 1em; + } + @else { + @return $value; +// @warn 'Everything is terrible! What have you done?!'; + } +} + +////////////////////////////// +// Returns whether the feature can have a min/max pair +////////////////////////////// +$breakpoint-min-max-features: 'color', + 'color-index', + 'aspect-ratio', + 'device-aspect-ratio', + 'device-height', + 'device-width', + 'height', + 'monochrome', + 'resolution', + 'width'; + +@function breakpoint-min-max($feature) { + @each $item in $breakpoint-min-max-features { + @if $feature == $item { + @return true; + } + } + @return false; +} + +////////////////////////////// +// Returns whether the feature can have a string value +////////////////////////////// +$breakpoint-string-features: 'orientation', + 'scan', + 'color', + 'aspect-ratio', + 'device-aspect-ratio', + 'pointer', + 'luminosity'; + +@function breakpoint-string-value($feature) { + @each $item in $breakpoint-string-features { + @if breakpoint-min-max($item) { + @if $feature == 'min-#{$item}' or $feature == 'max-#{$item}' { + @return true; + } + } + @else if $feature == $item { + @return true; + } + } + @return false; +} + +////////////////////////////// +// Returns whether the feature is a media type +////////////////////////////// +$breakpoint-media-types: 'all', + 'braille', + 'embossed', + 'handheld', + 'print', + 'projection', + 'screen', + 'speech', + 'tty', + 'tv'; + +@function breakpoint-is-media($feature) { + @each $media in $breakpoint-media-types { + @if ($feature == $media) or ($feature == 'not #{$media}') or ($feature == 'only #{$media}') { + @return true; + } + } + + @return false; +} + +////////////////////////////// +// Returns whether the feature can stand alone +////////////////////////////// +$breakpoint-single-string-features: 'color', + 'color-index', + 'grid', + 'monochrome'; + +@function breakpoint-single-string($feature) { + @each $item in $breakpoint-single-string-features { + @if $feature == $item { + @return true; + } + } + @return false; +} + +////////////////////////////// +// Returns whether the feature +////////////////////////////// +@function breakpoint-is-resolution($feature) { + $resolutions: 'device-pixel-ratio', 'dpr'; + + @if $breakpoint-resolutions { + $resolutions: append($resolutions, 'resolution'); + } + + @each $reso in $resolutions { + @if index($feature, $reso) or index($feature, 'min-#{$reso}') or index($feature, 'max-#{$reso}') { + @return true; + } + } + + @return false; +} diff --git a/ghost/admin/assets/sass/modules/breakpoint/_no-query.scss b/ghost/admin/assets/sass/modules/breakpoint/_no-query.scss new file mode 100755 index 0000000000..0b5a81f697 --- /dev/null +++ b/ghost/admin/assets/sass/modules/breakpoint/_no-query.scss @@ -0,0 +1,15 @@ +@function breakpoint-no-query($query) { + @if type-of($query) == 'list' { + $keyword: nth($query, 1); + + @if type-of($keyword) == 'string' and ($keyword == 'no-query' or $keyword == 'no query' or $keyword == 'fallback') { + @return nth($query, 2); + } + @else { + @return false; + } + } + @else { + @return false; + } +} diff --git a/ghost/admin/assets/sass/modules/breakpoint/_parsers.scss b/ghost/admin/assets/sass/modules/breakpoint/_parsers.scss new file mode 100755 index 0000000000..69123304fe --- /dev/null +++ b/ghost/admin/assets/sass/modules/breakpoint/_parsers.scss @@ -0,0 +1,104 @@ +////////////////////////////// +// Import Parser Pieces +////////////////////////////// +@import "parsers/query"; +@import "parsers/single"; +@import "parsers/double"; +@import "parsers/triple"; +@import "parsers/resolution"; + +////////////////////////////// +// General Breakpoint Parser +////////////////////////////// +@function breakpoint-parse($query) { + $private-breakpoint-context-placeholder: $private-breakpoint-context-placeholder + 1; + + // Set up Media Type + $query-print: ''; + + $force-all: (($breakpoint-force-media-all == true) and ($breakpoint-default-media == 'all')); + $empty-media: true; + @if ($force-all == true) or ($breakpoint-default-media != 'all') { + // Force the print of the default media type if (force all is true and default media type is all) or (default media type is not all) + $query-print: $breakpoint-default-media; + $empty-media: false; + } + + + $query-resolution: false; + + $query-holder: breakpoint-parse-query($query); + + + + // Loop over each parsed out query and write it to $query-print + $first: true; + + @each $feature in $query-holder { + $length: length($feature); + + // Parse a single feature + @if ($length == 1) { + // Feature is currenty a list, grab the actual value + $feature: nth($feature, 1); + + // Media Type must by convention be the first item, so it's safe to flat override $query-print, which right now should only be the default media type + @if (breakpoint-is-media($feature)) { + @if ($force-all == true) or ($feature != 'all') { + // Force the print of the default media type if (force all is true and default media type is all) or (default media type is not all) + $query-print: $feature; + $empty-media: false; + + // Set Context + $context-setter: private-breakpoint-set-context(media, $query-print); + } + } + @else { + $parsed: breakpoint-parse-single($feature, $empty-media, $first); + $query-print: '#{$query-print} #{$parsed}'; + $first: false; + } + } + // Parse a double feature + @else if ($length == 2) { + @if (breakpoint-is-resolution($feature) != false) { + $query-resolution: $feature; + } + @else { + $parsed: null; + // If it's a string/number pair, + // we check to see if one is a single-string value, + // then we parse it as a normal double + $alpha: nth($feature, 1); + $beta: nth($feature, 2); + @if breakpoint-single-string($alpha) or breakpoint-single-string($beta) { + $parsed: breakpoint-parse-single($alpha, $empty-media, $first); + $query-print: '#{$query-print} #{$parsed}'; + $first: false; + $parsed: breakpoint-parse-single($beta, $empty-media, $first); + $query-print: '#{$query-print} #{$parsed}'; + } + @else { + $parsed: breakpoint-parse-double($feature, $empty-media, $first); + $query-print: '#{$query-print} #{$parsed}'; + $first: false; + } + } + } + // Parse a triple feature + @else if ($length == 3) { + $parsed: breakpoint-parse-triple($feature, $empty-media, $first); + $query-print: '#{$query-print} #{$parsed}'; + $first: false; + } + + } + + @if ($query-resolution != false) { + $query-print: breakpoint-build-resolution($query-print, $query-resolution, $empty-media, $first); + } + + // @return 'all'; + + @return $query-print; +} diff --git a/ghost/admin/assets/sass/modules/breakpoint/_respond-to.scss b/ghost/admin/assets/sass/modules/breakpoint/_respond-to.scss new file mode 100755 index 0000000000..417db705e6 --- /dev/null +++ b/ghost/admin/assets/sass/modules/breakpoint/_respond-to.scss @@ -0,0 +1,55 @@ +//////////////////////// +// Default the Breakpoints variable +//////////////////////// +$breakpoints: () !default; + +//////////////////////// +// Respond-to API Mixin +//////////////////////// + +@mixin respond-to($context, $no-query: false) { + @if type-of($breakpoints) != 'list' { + // Just in case someone writes gibberish to the $breakpoints variable. + @warn "Your breakpoints aren't a list! See https://github.com/snugug/respond-to#api if you'd like a reminder on how to use Respond-to"; + } + @if length($breakpoints) != 0 { + // If there's only one breakpoint, SASS will think it's a space separated list :P + @if length($breakpoints) == 2 and type-of(nth($breakpoints, 1)) != 'list' { + $breakpoints: append((), (nth($breakpoints, 1), nth($breakpoints, 2))); + } + @each $bkpt in $breakpoints { + @if $context == nth($bkpt, 1) { + $length: length($bkpt); + $mq: false !default; + + @for $i from 2 through $length { + // If it's the first item, override $mq + @if $i == 2 { + $mq: nth($bkpt, $i); + } + // Else, join $mq + @else { + $mq: join($mq, nth($bkpt, $i)); + } + } + + @include breakpoint($mq, $no-query) { + @content; + } + } + } + } + @else { + @warn "You haven't created any breakpoints yet! Make some already! See https://github.com/snugug/respond-to#api if you'd like a reminder on how to use Respond-to"; + @content; + } +} + +////////////////////////////// +// Add Breakpoint to Breakpoints +////////////////////////////// +@function add-breakpoint($name, $bkpt) { + $bkpt: $name $bkpt; + $output: append($breakpoints, $bkpt, 'comma'); + @return $output; +} \ No newline at end of file diff --git a/ghost/admin/assets/sass/modules/breakpoint/parsers/_double.scss b/ghost/admin/assets/sass/modules/breakpoint/parsers/_double.scss new file mode 100755 index 0000000000..24580c1516 --- /dev/null +++ b/ghost/admin/assets/sass/modules/breakpoint/parsers/_double.scss @@ -0,0 +1,33 @@ +////////////////////////////// +// Import Pieces +////////////////////////////// +@import "double/default-pair"; +@import "double/double-string"; +@import "double/default"; + +@function breakpoint-parse-double($feature, $empty-media, $first) { + $parsed: ''; + $leader: ''; + // If we're forcing + @if not ($empty-media) or not ($first) { + $leader: 'and '; + } + + $first: nth($feature, 1); + $second: nth($feature, 2); + + // If we've got two numbers, we know we need to use the default pair because there are no media queries that has a media feature that is a number + @if type-of($first) == 'number' and type-of($second) == 'number' { + $parsed: breakpoint-parse-default-pair($first, $second); + } + // If they are both strings, we send it through the string parser + @else if type-of($first) == 'string' and type-of($second) == 'string' { + $parsed: breakpoint-parse-double-string($first, $second); + } + // If it's a string/number pair, we parse it as a normal double + @else { + $parsed: breakpoint-parse-double-default($first, $second); + } + + @return $leader + $parsed; +} diff --git a/ghost/admin/assets/sass/modules/breakpoint/parsers/_query.scss b/ghost/admin/assets/sass/modules/breakpoint/parsers/_query.scss new file mode 100755 index 0000000000..b8fa8f7613 --- /dev/null +++ b/ghost/admin/assets/sass/modules/breakpoint/parsers/_query.scss @@ -0,0 +1,75 @@ +@function breakpoint-parse-query($query) { + // Parse features out of an individual query + $feature-holder: (); + $query-holder: (); + $length: length($query); + + @if $length == 2 { + // If we've got a string/number, number/string, check to see if it's a valid string/number pair or two singles + @if (type-of(nth($query, 1)) == 'string' and type-of(nth($query, 2)) == 'number') or (type-of(nth($query, 1)) == 'number' and type-of(nth($query, 2)) == 'string') { + + $number: ''; + $value: ''; + + @if type-of(nth($query, 1)) == 'string' { + $number: nth($query, 2); + $value: nth($query, 1); + } + @else { + $number: nth($query, 1); + $value: nth($query, 2); + } + + // If the string value can be a single value, check to see if the number passed in is a valid input for said single value. Fortunately, all current single-value options only accept unitless numbers, so this check is easy. + @if breakpoint-single-string($value) { + @if unitless($number) { + $feature-holder: append($value, $number, space); + $query-holder: append($query-holder, $feature-holder, comma); + @return $query-holder; + } + } + // If the string is a media type, split the query + @if breakpoint-is-media($value) { + $query-holder: append($query-holder, nth($query, 1)); + $query-holder: append($query-holder, nth($query, 2)); + @return $query-holder; + } + // If it's not a single feature, we're just going to assume it's a proper string/value pair, and roll with it. + @else { + $feature-holder: append($value, $number, space); + $query-holder: append($query-holder, $feature-holder, comma); + @return $query-holder; + } + + } + // If they're both numbers, we assume it's a double and roll with that + @else if (type-of(nth($query, 1)) == 'number' and type-of(nth($query, 2)) == 'number') { + $feature-holder: append(nth($query, 1), nth($query, 2), space); + $query-holder: append($query-holder, $feature-holder, comma); + @return $query-holder; + } + // If they're both strings and neither are singles, we roll with that. + @else if (type-of(nth($query, 1)) == 'string' and type-of(nth($query, 2)) == 'string') { + @if not breakpoint-single-string(nth($query, 1)) and not breakpoint-single-string(nth($query, 2)) { + $feature-holder: append(nth($query, 1), nth($query, 2), space); + $query-holder: append($query-holder, $feature-holder, comma); + @return $query-holder; + } + } + } + @else if $length == 3 { + // If we've got three items and none is a list, we check to see + @if type-of(nth($query, 1)) != 'list' and type-of(nth($query, 2)) != 'list' and type-of(nth($query, 3)) != 'list' { + // If none of the items are single string values and none of the values are media values, we're good. + @if (not breakpoint-single-string(nth($query, 1)) and not breakpoint-single-string(nth($query, 2)) and not breakpoint-single-string(nth($query, 3))) and ((not breakpoint-is-media(nth($query, 1)) and not breakpoint-is-media(nth($query, 2)) and not breakpoint-is-media(nth($query, 3)))) { + $feature-holder: append(nth($query, 1), nth($query, 2), space); + $feature-holder: append($feature-holder, nth($query, 3), space); + $query-holder: append($query-holder, $feature-holder, comma); + @return $query-holder; + } + } + } + + // If it's a single item, or if it's not a special case double or tripple, we can simply return the query. + @return $query; +} diff --git a/ghost/admin/assets/sass/modules/breakpoint/parsers/_resolution.scss b/ghost/admin/assets/sass/modules/breakpoint/parsers/_resolution.scss new file mode 100755 index 0000000000..53a416223e --- /dev/null +++ b/ghost/admin/assets/sass/modules/breakpoint/parsers/_resolution.scss @@ -0,0 +1,31 @@ +@import "resolution/resolution"; + +@function breakpoint-build-resolution($query-print, $query-resolution, $empty-media, $first) { + $leader: ''; + // If we're forcing + @if not ($empty-media) or not ($first) { + $leader: 'and '; + } + + @if $breakpoint-resolutions and $query-resolution { + $resolutions: breakpoint-make-resolutions($query-resolution); + $length: length($resolutions); + $query-holder: ''; + + @for $i from 1 through $length { + $query: '#{$query-print} #{$leader}#{nth($resolutions, $i)}'; + @if $i == 1 { + $query-holder: $query; + } + @else { + $query-holder: '#{$query-holder}, #{$query}'; + } + } + + @return $query-holder; + } + @else { + // Return with attached resolution + @return $query-print; + } +} diff --git a/ghost/admin/assets/sass/modules/breakpoint/parsers/_single.scss b/ghost/admin/assets/sass/modules/breakpoint/parsers/_single.scss new file mode 100755 index 0000000000..d9fd764a72 --- /dev/null +++ b/ghost/admin/assets/sass/modules/breakpoint/parsers/_single.scss @@ -0,0 +1,26 @@ +////////////////////////////// +// Import Pieces +////////////////////////////// +@import "single/default"; + +@function breakpoint-parse-single($feature, $empty-media, $first) { + $parsed: ''; + $leader: ''; + // If we're forcing + @if not ($empty-media) or not ($first) { + $leader: 'and '; + } + + // If it's a single feature that can stand alone, we let it + @if (breakpoint-single-string($feature)) { + $parsed: $feature; + // Set Context + $context-setter: private-breakpoint-set-context($feature, $feature); + } + // If it's not a stand alone feature, we pass it off to the default handler. + @else { + $parsed: breakpoint-parse-default($feature); + } + + @return $leader + '(' + $parsed + ')'; +} diff --git a/ghost/admin/assets/sass/modules/breakpoint/parsers/_triple.scss b/ghost/admin/assets/sass/modules/breakpoint/parsers/_triple.scss new file mode 100755 index 0000000000..e2732067f9 --- /dev/null +++ b/ghost/admin/assets/sass/modules/breakpoint/parsers/_triple.scss @@ -0,0 +1,36 @@ +////////////////////////////// +// Import Pieces +////////////////////////////// +@import "triple/default"; + +@function breakpoint-parse-triple($feature, $empty-media, $first) { + $parsed: ''; + $leader: ''; + + // If we're forcing + @if not ($empty-media) or not ($first) { + $leader: 'and '; + } + + // separate the string features from the value numbers + $string: null; + $numbers: null; + @each $val in $feature { + @if type-of($val) == string { + $string: $val; + } + @else { + @if type-of($numbers) == 'null' { + $numbers: $val; + } + @else { + $numbers: append($numbers, $val); + } + } + } + + $parsed: breakpoint-parse-triple-default($string, nth($numbers, 1), nth($numbers, 2)); + + @return $leader + $parsed; + +} diff --git a/ghost/admin/assets/sass/modules/breakpoint/parsers/double/_default-pair.scss b/ghost/admin/assets/sass/modules/breakpoint/parsers/double/_default-pair.scss new file mode 100755 index 0000000000..27e0bdbc9b --- /dev/null +++ b/ghost/admin/assets/sass/modules/breakpoint/parsers/double/_default-pair.scss @@ -0,0 +1,21 @@ +@function breakpoint-parse-default-pair($first, $second) { + $default: $breakpoint-default-pair; + $min: ''; + $max: ''; + + // Sort into min and max + $min: min($first, $second); + $max: max($first, $second); + + // Set Context + $context-setter: private-breakpoint-set-context(min-#{$default}, $min); + $context-setter: private-breakpoint-set-context(max-#{$default}, $max); + + // Make them EMs if need be + @if ($breakpoint-to-ems == true) { + $min: breakpoint-to-base-em($min); + $max: breakpoint-to-base-em($max); + } + + @return '(min-#{$default}: #{$min}) and (max-#{$default}: #{$max})'; +} diff --git a/ghost/admin/assets/sass/modules/breakpoint/parsers/double/_default.scss b/ghost/admin/assets/sass/modules/breakpoint/parsers/double/_default.scss new file mode 100755 index 0000000000..a19a2f4723 --- /dev/null +++ b/ghost/admin/assets/sass/modules/breakpoint/parsers/double/_default.scss @@ -0,0 +1,22 @@ +@function breakpoint-parse-double-default($first, $second) { + $feature: ''; + $value: ''; + + @if type-of($first) == 'string' { + $feature: $first; + $value: $second; + } + @else { + $feature: $second; + $value: $first; + } + + // Set Context + $context-setter: private-breakpoint-set-context($feature, $value); + + @if ($breakpoint-to-ems == true) { + $value: breakpoint-to-base-em($value); + } + + @return '(#{$feature}: #{$value})' +} diff --git a/ghost/admin/assets/sass/modules/breakpoint/parsers/double/_double-string.scss b/ghost/admin/assets/sass/modules/breakpoint/parsers/double/_double-string.scss new file mode 100755 index 0000000000..4c5ce4651c --- /dev/null +++ b/ghost/admin/assets/sass/modules/breakpoint/parsers/double/_double-string.scss @@ -0,0 +1,19 @@ +@function breakpoint-parse-double-string($first, $second) { + $feature: ''; + $value: ''; + + // Test to see which is the feature and which is the value + @if (breakpoint-string-value($first) == true) { + $feature: $first; + $value: $second; + } + @else { + $feature: $second; + $value: $first; + } + + // Set Context + $context-setter: private-breakpoint-set-context($feature, $value); + + @return '(#{$feature}: #{$value})'; +} diff --git a/ghost/admin/assets/sass/modules/breakpoint/parsers/resolution/_resolution.scss b/ghost/admin/assets/sass/modules/breakpoint/parsers/resolution/_resolution.scss new file mode 100755 index 0000000000..3680421269 --- /dev/null +++ b/ghost/admin/assets/sass/modules/breakpoint/parsers/resolution/_resolution.scss @@ -0,0 +1,60 @@ +@function breakpoint-make-resolutions($resolution) { + $length: length($resolution); + + $output: (); + + @if $length == 2 { + $feature: ''; + $value: ''; + + // Find which is number + @if type-of(nth($resolution, 1)) == 'number' { + $value: nth($resolution, 1); + } + @else { + $value: nth($resolution, 2); + } + + // Determine min/max/standard + @if index($resolution, 'min-resolution') { + $feature: 'min-'; + } + @else if index($resolution, 'max-resolution') { + $feature: 'max-'; + } + + $standard: '(#{$feature}resolution: #{$value})'; + + // If we're not dealing with dppx, + @if unit($value) != 'dppx' { + $base: 96dpi; + @if unit($value) == 'dpcm' { + $base: 243.84dpcm; + } + // Write out feature tests + $webkit: ''; + $moz: ''; + $webkit: '(-webkit-#{$feature}device-pixel-ratio: #{$value / $base})'; + $moz: '(#{$feature}-moz-device-pixel-ratio: #{$value / $base})'; + // Append to output + $output: append($output, $standard, space); + $output: append($output, $webkit, space); + $output: append($output, $moz, space); + } + @else { + $webkit: ''; + $moz: ''; + $webkit: '(-webkit-#{$feature}device-pixel-ratio: #{$value / 1dppx})'; + $moz: '(#{$feature}-moz-device-pixel-ratio: #{$value / 1dppx})'; + $fallback: '(#{$feature}resolution: #{$value / 1dppx * 96dpi})'; + // Append to output + $output: append($output, $standard, space); + $output: append($output, $webkit, space); + $output: append($output, $moz, space); + $output: append($output, $fallback, space); + } + + } + + @return $output; +} diff --git a/ghost/admin/assets/sass/modules/breakpoint/parsers/single/_default.scss b/ghost/admin/assets/sass/modules/breakpoint/parsers/single/_default.scss new file mode 100755 index 0000000000..bb3a753e2c --- /dev/null +++ b/ghost/admin/assets/sass/modules/breakpoint/parsers/single/_default.scss @@ -0,0 +1,13 @@ +@function breakpoint-parse-default($feature) { + $default: $breakpoint-default-feature; + + // Set Context + $context-setter: private-breakpoint-set-context($default, $feature); + + @if ($breakpoint-to-ems == true) and (type-of($feature) == 'number') { + @return '#{$default}: #{breakpoint-to-base-em($feature)}'; + } + @else { + @return '#{$default}: #{$feature}'; + } +} diff --git a/ghost/admin/assets/sass/modules/breakpoint/parsers/triple/_default.scss b/ghost/admin/assets/sass/modules/breakpoint/parsers/triple/_default.scss new file mode 100755 index 0000000000..da256bd3ad --- /dev/null +++ b/ghost/admin/assets/sass/modules/breakpoint/parsers/triple/_default.scss @@ -0,0 +1,18 @@ +@function breakpoint-parse-triple-default($feature, $first, $second) { + + // Sort into min and max + $min: min($first, $second); + $max: max($first, $second); + + // Set Context + $context-setter: private-breakpoint-set-context(min-#{$feature}, $min); + $context-setter: private-breakpoint-set-context(max-#{$feature}, $max); + + // Make them EMs if need be + @if ($breakpoint-to-ems == true) { + $min: breakpoint-to-base-em($min); + $max: breakpoint-to-base-em($max); + } + + @return '(min-#{$feature}: #{$min}) and (max-#{$feature}: #{$max})'; +}