mostly filebased Content Presentation System

262 linhas
6.9KB

  1. /// Syntax Normalization
  2. /// ====================
  3. /// Susy is divided into two layers:
  4. /// "Su" provides the core math functions with a stripped-down syntax,
  5. /// while "Susy" adds global settings, shorthand syntax,
  6. /// and other helpers.
  7. /// Each setting (e.g. span, location, columns, spread, etc.)
  8. /// has a single canonical syntax in Su.
  9. ///
  10. /// This normalization module helps translate between those layers,
  11. /// transforming parsed Susy input into
  12. /// values that Su will understand.
  13. ///
  14. /// @group _normal
  15. ///
  16. /// @see susy-normalize
  17. /// @see susy-normalize-span
  18. /// @see susy-normalize-columns
  19. /// @see susy-normalize-spread
  20. /// @see susy-normalize-location
  21. // Susy Normalize
  22. // --------------
  23. /// Normalize the values in a configuration map.
  24. /// In addition to the global `$susy` properties,
  25. /// this map can include local span-related imformation,
  26. /// like `span` and `location`.
  27. ///
  28. /// Normalization does not check that values are valid,
  29. /// which will happen in the Su math layer.
  30. /// These functions merely look for known Susy syntax –
  31. /// returning a map with those shorthand values
  32. /// converted into low-level data for Su.
  33. /// For example `span: all` and `location: first`
  34. /// will be converted into specific numbers.
  35. ///
  36. /// @group _normal
  37. /// @see $susy
  38. /// @see susy-parse
  39. ///
  40. /// @param {map} $config -
  41. /// Map of Susy configuration settings to normalize.
  42. /// See `$susy` and `susy-parse()` documentation for details.
  43. /// @param {map | null} $context [null] -
  44. /// Map of Susy configuration settings to use as global reference,
  45. /// or `null` to use global settings.
  46. ///
  47. /// @return {map} -
  48. /// Map of Susy configuration settings,
  49. /// with all values normalized for Su math functions.
  50. @function susy-normalize(
  51. $config,
  52. $context: null
  53. ) {
  54. // Spread
  55. @each $setting in ('spread', 'container-spread') {
  56. $value: map-get($config, $setting);
  57. @if $value {
  58. $value: susy-normalize-spread($value);
  59. $config: map-merge($config, ($setting: $value));
  60. }
  61. }
  62. // Columns
  63. $columns: map-get($config, 'columns');
  64. @if $columns {
  65. $columns: susy-normalize-columns($columns, $context);
  66. $config: map-merge($config, ('columns': $columns));
  67. }
  68. @if not $columns {
  69. $map: type-of($context) == 'map';
  70. $columns: if($map, map-get($context, 'columns'), null);
  71. $columns: $columns or susy-get('columns');
  72. }
  73. // Span
  74. $span: map-get($config, 'span');
  75. @if $span {
  76. $span: susy-normalize-span($span, $columns);
  77. $config: map-merge($config, ('span': $span));
  78. }
  79. // Location
  80. $location: map-get($config, 'location');
  81. @if $location {
  82. $location: susy-normalize-location($span, $location, $columns);
  83. $config: map-merge($config, ('location': $location));
  84. }
  85. @return $config;
  86. }
  87. // Normalize Span
  88. // --------------
  89. /// Normalize `span` shorthand for Su.
  90. /// Su span syntax allows an explicit length (e.g. `3em`),
  91. /// unitless column-span number (e.g. `3` columns),
  92. /// or an explicit list of columns (e.g. `(3 5 8)`).
  93. ///
  94. /// Susy span syntax also allows the `all` keyword,
  95. /// which will be converted to a slice of the context
  96. /// in normalization.
  97. ///
  98. /// @group _normal
  99. ///
  100. /// @param {number | list | 'all'} $span -
  101. /// Span value to normalize.
  102. /// @param {list} $columns -
  103. /// Normalized list of columns in the grid
  104. ///
  105. /// @return {number | list} -
  106. /// Number or list value for `$span`
  107. @function susy-normalize-span(
  108. $span,
  109. $columns: susy-get('columns')
  110. ) {
  111. @if ($span == 'all') {
  112. @return length($columns);
  113. }
  114. @return $span;
  115. }
  116. // Normalize Columns
  117. // -----------------
  118. /// Normalize `column` shorthand for Su.
  119. /// Su column syntax only allows column lists (e.g. `120px 1 1 1 120px`).
  120. ///
  121. /// Susy span syntax also allows a unitless `slice` number (e.g `of 5`),
  122. /// which will be converted to a slice of the context
  123. /// in normalization.
  124. ///
  125. /// @group _normal
  126. ///
  127. /// @param {list | integer} $columns -
  128. /// List of available columns,
  129. /// or unitless integer representing a slice of
  130. /// the available context.
  131. /// @param {map | null} $context [null] -
  132. /// Map of Susy configuration settings to use as global reference,
  133. /// or `null` to access global settings.
  134. ///
  135. /// @return {list} -
  136. /// Columns list value, normalized for Su input.
  137. ///
  138. /// @throws
  139. /// when attempting to access a slice of asymmetrical context
  140. @function susy-normalize-columns(
  141. $columns,
  142. $context: null
  143. ) {
  144. $context: $context or susy-settings();
  145. @if type-of($columns) == 'list' {
  146. @return _susy-flatten($columns);
  147. }
  148. @if (type-of($columns) == 'number') and (unitless($columns)) {
  149. $span: $columns;
  150. $context: map-get($context, 'columns');
  151. $symmetrical: susy-repeat(length($context), nth($context, 1));
  152. @if ($context == $symmetrical) {
  153. @return susy-repeat($span, nth($context, 1));
  154. } @else {
  155. $actual: 'of `#{$span}`';
  156. $columns: 'grid-columns `#{$context}`';
  157. @return _susy-error(
  158. 'context-slice #{$actual} can not be determined based on #{$columns}.',
  159. 'susy-normalize-columns');
  160. }
  161. }
  162. @return $columns;
  163. }
  164. // Normalize Spread
  165. // ----------------
  166. /// Normalize `spread` shorthand for Su.
  167. /// Su spread syntax only allows the numbers `-1`, `0`, or `1` –
  168. /// representing the number of gutters covered
  169. /// in relation to columns spanned.
  170. ///
  171. /// Susy spread syntax also allows keywords for each value –
  172. /// `narrow` for `-1`, `wide` for `0`, or `wider` for `1` –
  173. /// which will be converted to their respective integers
  174. /// in normalization.
  175. ///
  176. /// @group _normal
  177. ///
  178. /// @param {0 | 1 | -1 | 'narrow' | 'wide' | 'wider'} $spread -
  179. /// Spread across adjacent gutters, relative to a column-count —
  180. /// either `narrow` (-1), `wide` (0), or `wider` (1)
  181. ///
  182. /// @return {number} -
  183. /// Numeric value for `$spread`
  184. @function susy-normalize-spread(
  185. $spread
  186. ) {
  187. $normal-spread: (
  188. 'narrow': -1,
  189. 'wide': 0,
  190. 'wider': 1,
  191. );
  192. @return map-get($normal-spread, $spread) or $spread;
  193. }
  194. // Normalize Location
  195. // ------------------
  196. /// Normalize `location` shorthand for Su.
  197. /// Su location syntax requires the (1-indexed) number for a column.
  198. ///
  199. /// Susy also allows the `first` and `last` keywords,
  200. /// where `first` is always `1`,
  201. /// and `last` is calculated based on span and column values.
  202. /// Both keywords are normalized into an integer index
  203. /// in normalization.
  204. ///
  205. /// @group _normal
  206. ///
  207. /// @param {number} $span -
  208. /// Number of grid-columns to be spanned
  209. /// @param {integer | 'first' | 'last'} $location -
  210. /// Starting (1-indexed) column position of a span,
  211. /// or a named location keyword.
  212. /// @param {list} $columns -
  213. /// Already-normalized list of columns in the grid.
  214. ///
  215. /// @return {integer} -
  216. /// Numeric value for `$location`
  217. @function susy-normalize-location(
  218. $span,
  219. $location,
  220. $columns
  221. ) {
  222. $count: length($columns);
  223. $normal-locations: (
  224. 'first': 1,
  225. 'alpha': 1,
  226. 'last': $count - $span + 1,
  227. 'omega': $count - $span + 1,
  228. );
  229. @return map-get($normal-locations, $location) or $location;
  230. }