123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193 |
- /*jshint node:true */
- /*
- The MIT License (MIT)
- Copyright (c) 2007-2018 Einar Lielmanis, Liam Newman, and contributors.
- Permission is hereby granted, free of charge, to any person
- obtaining a copy of this software and associated documentation files
- (the "Software"), to deal in the Software without restriction,
- including without limitation the rights to use, copy, modify, merge,
- publish, distribute, sublicense, and/or sell copies of the Software,
- and to permit persons to whom the Software is furnished to do so,
- subject to the following conditions:
- The above copyright notice and this permission notice shall be
- included in all copies or substantial portions of the Software.
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
- BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
- ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
- CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- SOFTWARE.
- */
- 'use strict';
- function Options(options, merge_child_field) {
- this.raw_options = _mergeOpts(options, merge_child_field);
- // Support passing the source text back with no change
- this.disabled = this._get_boolean('disabled');
- this.eol = this._get_characters('eol', 'auto');
- this.end_with_newline = this._get_boolean('end_with_newline');
- this.indent_size = this._get_number('indent_size', 4);
- this.indent_char = this._get_characters('indent_char', ' ');
- this.indent_level = this._get_number('indent_level');
- this.preserve_newlines = this._get_boolean('preserve_newlines', true);
- this.max_preserve_newlines = this._get_number('max_preserve_newlines', 32786);
- if (!this.preserve_newlines) {
- this.max_preserve_newlines = 0;
- }
- this.indent_with_tabs = this._get_boolean('indent_with_tabs', this.indent_char === '\t');
- if (this.indent_with_tabs) {
- this.indent_char = '\t';
- // indent_size behavior changed after 1.8.6
- // It used to be that indent_size would be
- // set to 1 for indent_with_tabs. That is no longer needed and
- // actually doesn't make sense - why not use spaces? Further,
- // that might produce unexpected behavior - tabs being used
- // for single-column alignment. So, when indent_with_tabs is true
- // and indent_size is 1, reset indent_size to 4.
- if (this.indent_size === 1) {
- this.indent_size = 4;
- }
- }
- // Backwards compat with 1.3.x
- this.wrap_line_length = this._get_number('wrap_line_length', this._get_number('max_char'));
- this.indent_empty_lines = this._get_boolean('indent_empty_lines');
- // valid templating languages ['django', 'erb', 'handlebars', 'php']
- // For now, 'auto' = all off for javascript, all on for html (and inline javascript).
- // other values ignored
- this.templating = this._get_selection_list('templating', ['auto', 'none', 'django', 'erb', 'handlebars', 'php'], ['auto']);
- }
- Options.prototype._get_array = function(name, default_value) {
- var option_value = this.raw_options[name];
- var result = default_value || [];
- if (typeof option_value === 'object') {
- if (option_value !== null && typeof option_value.concat === 'function') {
- result = option_value.concat();
- }
- } else if (typeof option_value === 'string') {
- result = option_value.split(/[^a-zA-Z0-9_\/\-]+/);
- }
- return result;
- };
- Options.prototype._get_boolean = function(name, default_value) {
- var option_value = this.raw_options[name];
- var result = option_value === undefined ? !!default_value : !!option_value;
- return result;
- };
- Options.prototype._get_characters = function(name, default_value) {
- var option_value = this.raw_options[name];
- var result = default_value || '';
- if (typeof option_value === 'string') {
- result = option_value.replace(/\\r/, '\r').replace(/\\n/, '\n').replace(/\\t/, '\t');
- }
- return result;
- };
- Options.prototype._get_number = function(name, default_value) {
- var option_value = this.raw_options[name];
- default_value = parseInt(default_value, 10);
- if (isNaN(default_value)) {
- default_value = 0;
- }
- var result = parseInt(option_value, 10);
- if (isNaN(result)) {
- result = default_value;
- }
- return result;
- };
- Options.prototype._get_selection = function(name, selection_list, default_value) {
- var result = this._get_selection_list(name, selection_list, default_value);
- if (result.length !== 1) {
- throw new Error(
- "Invalid Option Value: The option '" + name + "' can only be one of the following values:\n" +
- selection_list + "\nYou passed in: '" + this.raw_options[name] + "'");
- }
- return result[0];
- };
- Options.prototype._get_selection_list = function(name, selection_list, default_value) {
- if (!selection_list || selection_list.length === 0) {
- throw new Error("Selection list cannot be empty.");
- }
- default_value = default_value || [selection_list[0]];
- if (!this._is_valid_selection(default_value, selection_list)) {
- throw new Error("Invalid Default Value!");
- }
- var result = this._get_array(name, default_value);
- if (!this._is_valid_selection(result, selection_list)) {
- throw new Error(
- "Invalid Option Value: The option '" + name + "' can contain only the following values:\n" +
- selection_list + "\nYou passed in: '" + this.raw_options[name] + "'");
- }
- return result;
- };
- Options.prototype._is_valid_selection = function(result, selection_list) {
- return result.length && selection_list.length &&
- !result.some(function(item) { return selection_list.indexOf(item) === -1; });
- };
- // merges child options up with the parent options object
- // Example: obj = {a: 1, b: {a: 2}}
- // mergeOpts(obj, 'b')
- //
- // Returns: {a: 2}
- function _mergeOpts(allOptions, childFieldName) {
- var finalOpts = {};
- allOptions = _normalizeOpts(allOptions);
- var name;
- for (name in allOptions) {
- if (name !== childFieldName) {
- finalOpts[name] = allOptions[name];
- }
- }
- //merge in the per type settings for the childFieldName
- if (childFieldName && allOptions[childFieldName]) {
- for (name in allOptions[childFieldName]) {
- finalOpts[name] = allOptions[childFieldName][name];
- }
- }
- return finalOpts;
- }
- function _normalizeOpts(options) {
- var convertedOpts = {};
- var key;
- for (key in options) {
- var newKey = key.replace(/-/g, "_");
- convertedOpts[newKey] = options[key];
- }
- return convertedOpts;
- }
- module.exports.Options = Options;
- module.exports.normalizeOpts = _normalizeOpts;
- module.exports.mergeOpts = _mergeOpts;
|