-
-
Notifications
You must be signed in to change notification settings - Fork 12
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #2 from naztronaut/brightnessButtonsSlider
Brightness buttons slider
- Loading branch information
Showing
6 changed files
with
466 additions
and
12 deletions.
There are no files selected for viewing
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,335 @@ | ||
(function(){ | ||
|
||
'use strict'; | ||
|
||
var | ||
/** @const */ FormatOptions = [ | ||
'decimals', | ||
'thousand', | ||
'mark', | ||
'prefix', | ||
'postfix', | ||
'encoder', | ||
'decoder', | ||
'negativeBefore', | ||
'negative', | ||
'edit', | ||
'undo' | ||
]; | ||
|
||
// General | ||
|
||
// Reverse a string | ||
function strReverse ( a ) { | ||
return a.split('').reverse().join(''); | ||
} | ||
|
||
// Check if a string starts with a specified prefix. | ||
function strStartsWith ( input, match ) { | ||
return input.substring(0, match.length) === match; | ||
} | ||
|
||
// Check is a string ends in a specified postfix. | ||
function strEndsWith ( input, match ) { | ||
return input.slice(-1 * match.length) === match; | ||
} | ||
|
||
// Throw an error if formatting options are incompatible. | ||
function throwEqualError( F, a, b ) { | ||
if ( (F[a] || F[b]) && (F[a] === F[b]) ) { | ||
throw new Error(a); | ||
} | ||
} | ||
|
||
// Check if a number is finite and not NaN | ||
function isValidNumber ( input ) { | ||
return typeof input === 'number' && isFinite( input ); | ||
} | ||
|
||
// Provide rounding-accurate toFixed method. | ||
function toFixed ( value, decimals ) { | ||
var scale = Math.pow(10, decimals); | ||
return ( Math.round(value * scale) / scale).toFixed( decimals ); | ||
} | ||
|
||
|
||
// Formatting | ||
|
||
// Accept a number as input, output formatted string. | ||
function formatTo ( decimals, thousand, mark, prefix, postfix, encoder, decoder, negativeBefore, negative, edit, undo, input ) { | ||
|
||
var originalInput = input, inputIsNegative, inputPieces, inputBase, inputDecimals = '', output = ''; | ||
|
||
// Apply user encoder to the input. | ||
// Expected outcome: number. | ||
if ( encoder ) { | ||
input = encoder(input); | ||
} | ||
|
||
// Stop if no valid number was provided, the number is infinite or NaN. | ||
if ( !isValidNumber(input) ) { | ||
return false; | ||
} | ||
|
||
// Rounding away decimals might cause a value of -0 | ||
// when using very small ranges. Remove those cases. | ||
if ( decimals !== false && parseFloat(input.toFixed(decimals)) === 0 ) { | ||
input = 0; | ||
} | ||
|
||
// Formatting is done on absolute numbers, | ||
// decorated by an optional negative symbol. | ||
if ( input < 0 ) { | ||
inputIsNegative = true; | ||
input = Math.abs(input); | ||
} | ||
|
||
// Reduce the number of decimals to the specified option. | ||
if ( decimals !== false ) { | ||
input = toFixed( input, decimals ); | ||
} | ||
|
||
// Transform the number into a string, so it can be split. | ||
input = input.toString(); | ||
|
||
// Break the number on the decimal separator. | ||
if ( input.indexOf('.') !== -1 ) { | ||
inputPieces = input.split('.'); | ||
|
||
inputBase = inputPieces[0]; | ||
|
||
if ( mark ) { | ||
inputDecimals = mark + inputPieces[1]; | ||
} | ||
|
||
} else { | ||
|
||
// If it isn't split, the entire number will do. | ||
inputBase = input; | ||
} | ||
|
||
// Group numbers in sets of three. | ||
if ( thousand ) { | ||
inputBase = strReverse(inputBase).match(/.{1,3}/g); | ||
inputBase = strReverse(inputBase.join( strReverse( thousand ) )); | ||
} | ||
|
||
// If the number is negative, prefix with negation symbol. | ||
if ( inputIsNegative && negativeBefore ) { | ||
output += negativeBefore; | ||
} | ||
|
||
// Prefix the number | ||
if ( prefix ) { | ||
output += prefix; | ||
} | ||
|
||
// Normal negative option comes after the prefix. Defaults to '-'. | ||
if ( inputIsNegative && negative ) { | ||
output += negative; | ||
} | ||
|
||
// Append the actual number. | ||
output += inputBase; | ||
output += inputDecimals; | ||
|
||
// Apply the postfix. | ||
if ( postfix ) { | ||
output += postfix; | ||
} | ||
|
||
// Run the output through a user-specified post-formatter. | ||
if ( edit ) { | ||
output = edit ( output, originalInput ); | ||
} | ||
|
||
// All done. | ||
return output; | ||
} | ||
|
||
// Accept a sting as input, output decoded number. | ||
function formatFrom ( decimals, thousand, mark, prefix, postfix, encoder, decoder, negativeBefore, negative, edit, undo, input ) { | ||
|
||
var originalInput = input, inputIsNegative, output = ''; | ||
|
||
// User defined pre-decoder. Result must be a non empty string. | ||
if ( undo ) { | ||
input = undo(input); | ||
} | ||
|
||
// Test the input. Can't be empty. | ||
if ( !input || typeof input !== 'string' ) { | ||
return false; | ||
} | ||
|
||
// If the string starts with the negativeBefore value: remove it. | ||
// Remember is was there, the number is negative. | ||
if ( negativeBefore && strStartsWith(input, negativeBefore) ) { | ||
input = input.replace(negativeBefore, ''); | ||
inputIsNegative = true; | ||
} | ||
|
||
// Repeat the same procedure for the prefix. | ||
if ( prefix && strStartsWith(input, prefix) ) { | ||
input = input.replace(prefix, ''); | ||
} | ||
|
||
// And again for negative. | ||
if ( negative && strStartsWith(input, negative) ) { | ||
input = input.replace(negative, ''); | ||
inputIsNegative = true; | ||
} | ||
|
||
// Remove the postfix. | ||
// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/slice | ||
if ( postfix && strEndsWith(input, postfix) ) { | ||
input = input.slice(0, -1 * postfix.length); | ||
} | ||
|
||
// Remove the thousand grouping. | ||
if ( thousand ) { | ||
input = input.split(thousand).join(''); | ||
} | ||
|
||
// Set the decimal separator back to period. | ||
if ( mark ) { | ||
input = input.replace(mark, '.'); | ||
} | ||
|
||
// Prepend the negative symbol. | ||
if ( inputIsNegative ) { | ||
output += '-'; | ||
} | ||
|
||
// Add the number | ||
output += input; | ||
|
||
// Trim all non-numeric characters (allow '.' and '-'); | ||
output = output.replace(/[^0-9\.\-.]/g, ''); | ||
|
||
// The value contains no parse-able number. | ||
if ( output === '' ) { | ||
return false; | ||
} | ||
|
||
// Covert to number. | ||
output = Number(output); | ||
|
||
// Run the user-specified post-decoder. | ||
if ( decoder ) { | ||
output = decoder(output); | ||
} | ||
|
||
// Check is the output is valid, otherwise: return false. | ||
if ( !isValidNumber(output) ) { | ||
return false; | ||
} | ||
|
||
return output; | ||
} | ||
|
||
|
||
// Framework | ||
|
||
// Validate formatting options | ||
function validate ( inputOptions ) { | ||
|
||
var i, optionName, optionValue, | ||
filteredOptions = {}; | ||
|
||
for ( i = 0; i < FormatOptions.length; i+=1 ) { | ||
|
||
optionName = FormatOptions[i]; | ||
optionValue = inputOptions[optionName]; | ||
|
||
if ( optionValue === undefined ) { | ||
|
||
// Only default if negativeBefore isn't set. | ||
if ( optionName === 'negative' && !filteredOptions.negativeBefore ) { | ||
filteredOptions[optionName] = '-'; | ||
// Don't set a default for mark when 'thousand' is set. | ||
} else if ( optionName === 'mark' && filteredOptions.thousand !== '.' ) { | ||
filteredOptions[optionName] = '.'; | ||
} else { | ||
filteredOptions[optionName] = false; | ||
} | ||
|
||
// Floating points in JS are stable up to 7 decimals. | ||
} else if ( optionName === 'decimals' ) { | ||
if ( optionValue >= 0 && optionValue < 8 ) { | ||
filteredOptions[optionName] = optionValue; | ||
} else { | ||
throw new Error(optionName); | ||
} | ||
|
||
// These options, when provided, must be functions. | ||
} else if ( optionName === 'encoder' || optionName === 'decoder' || optionName === 'edit' || optionName === 'undo' ) { | ||
if ( typeof optionValue === 'function' ) { | ||
filteredOptions[optionName] = optionValue; | ||
} else { | ||
throw new Error(optionName); | ||
} | ||
|
||
// Other options are strings. | ||
} else { | ||
|
||
if ( typeof optionValue === 'string' ) { | ||
filteredOptions[optionName] = optionValue; | ||
} else { | ||
throw new Error(optionName); | ||
} | ||
} | ||
} | ||
|
||
// Some values can't be extracted from a | ||
// string if certain combinations are present. | ||
throwEqualError(filteredOptions, 'mark', 'thousand'); | ||
throwEqualError(filteredOptions, 'prefix', 'negative'); | ||
throwEqualError(filteredOptions, 'prefix', 'negativeBefore'); | ||
|
||
return filteredOptions; | ||
} | ||
|
||
// Pass all options as function arguments | ||
function passAll ( options, method, input ) { | ||
var i, args = []; | ||
|
||
// Add all options in order of FormatOptions | ||
for ( i = 0; i < FormatOptions.length; i+=1 ) { | ||
args.push(options[FormatOptions[i]]); | ||
} | ||
|
||
// Append the input, then call the method, presenting all | ||
// options as arguments. | ||
args.push(input); | ||
return method.apply('', args); | ||
} | ||
|
||
/** @constructor */ | ||
function wNumb ( options ) { | ||
|
||
if ( !(this instanceof wNumb) ) { | ||
return new wNumb ( options ); | ||
} | ||
|
||
if ( typeof options !== "object" ) { | ||
return; | ||
} | ||
|
||
options = validate(options); | ||
|
||
// Call 'formatTo' with proper arguments. | ||
this.to = function ( input ) { | ||
return passAll(options, formatTo, input); | ||
}; | ||
|
||
// Call 'formatFrom' with proper arguments. | ||
this.from = function ( input ) { | ||
return passAll(options, formatFrom, input); | ||
}; | ||
} | ||
|
||
/** @export */ | ||
window.wNumb = wNumb; | ||
|
||
}()); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.