Вход Регистрация
Файл: forsoc.ru/manul/static/js/bootbox.js
Строк: 905
<?php
/**
 * bootbox.js [master branch]
 *
 * http://bootboxjs.com/license.txt
 */

// @see https://github.com/makeusabrew/bootbox/issues/180
// @see https://github.com/makeusabrew/bootbox/issues/186
(function (rootfactory) {

  
"use strict";
  if (
typeof define === "function" && define.amd) {
    
// AMD. Register as an anonymous module.
    
define(["jquery"], factory);
  } else if (
typeof exports === "object") {
    
// Node. Does not work with strict CommonJS, but
    // only CommonJS-like environments that support module.exports,
    // like Node.
    
module.exports factory(require("jquery"));
  } else {
    
// Browser globals (root is window)
    
root.bootbox factory(root.jQuery);
  }

}(
this, function init($, undefined) {

  
"use strict";

  
// the base DOM structure needed to create a modal
  
var templates = {
    
dialog:
      
"<div class='bootbox modal' tabindex='-1' role='dialog'>" +
        
"<div class='modal-dialog'>" +
          
"<div class='modal-content'>" +
            
"<div class='modal-body'><div class='bootbox-body'></div></div>" +
          
"</div>" +
        
"</div>" +
      
"</div>",
    
header:
      
"<div class='modal-header'>" +
        
"<h4 class='modal-title'></h4>" +
      
"</div>",
    
footer:
      
"<div class='modal-footer'></div>",
    
closeButton:
      
"<button type='button' class='bootbox-close-button close' data-dismiss='modal' aria-hidden='true'>&times;</button>",
    
form:
      
"<form class='bootbox-form'></form>",
    
inputs: {
      
text:
        
"<input class='bootbox-input bootbox-input-text form-control' autocomplete=off type=text />",
      
textarea:
        
"<textarea class='bootbox-input bootbox-input-textarea form-control'></textarea>",
      
email:
        
"<input class='bootbox-input bootbox-input-email form-control' autocomplete='off' type='email' />",
      
select:
        
"<select class='bootbox-input bootbox-input-select form-control'></select>",
      
checkbox:
        
"<div class='checkbox'><label><input class='bootbox-input bootbox-input-checkbox' type='checkbox' /></label></div>",
      
date:
        
"<input class='bootbox-input bootbox-input-date form-control' autocomplete=off type='date' />",
      
time:
        
"<input class='bootbox-input bootbox-input-time form-control' autocomplete=off type='time' />",
      
number:
        
"<input class='bootbox-input bootbox-input-number form-control' autocomplete=off type='number' />",
      
password:
        
"<input class='bootbox-input bootbox-input-password form-control' autocomplete='off' type='password' />"
    
}
  };

  var 
defaults = {
    
// default language
    
locale"en",
    
// show backdrop or not
    
backdroptrue,
    
// animate the modal in/out
    
animatetrue,
    
// additional class string applied to the top level dialog
    
classNamenull,
    
// whether or not to include a close button
    
closeButtontrue,
    
// show the dialog immediately by default
    
showtrue,
    
// dialog container
    
container"body"
  
};

  
// our public object; augmented after our private API
  
var exports = {};

  
/**
   * @private
   */
  
function _t(key) {
    var 
locale locales[defaults.locale];
    return 
locale locale[key] : locales.en[key];
  }

  function 
processCallback(edialogcallback) {
    
e.stopPropagation();
    
e.preventDefault();

    
// by default we assume a callback will get rid of the dialog,
    // although it is given the opportunity to override this

    // so, if the callback can be invoked and it *explicitly returns false*
    // then we'll set a flag to keep the dialog active...
    
var preserveDialog = $.isFunction(callback) && callback(e) === false;

    
// ... otherwise we'll bin it
    
if (!preserveDialog) {
      
dialog.modal("hide");
    }
  }

  function 
getKeyLength(obj) {
    
// @TODO defer to Object.keys(x).length if available?
    
var k0;
    for (
k in obj) {
      
++;
    }
    return 
t;
  }

  function 
each(collectioniterator) {
    var 
index 0;
    $.
each(collection, function(keyvalue) {
      
iterator(keyvalueindex++);
    });
  }

  function 
sanitize(options) {
    var 
buttons;
    var 
total;

    if (
typeof options !== "object") {
      throw new 
Error("Please supply an object of options");
    }

    if (!
options.message) {
      throw new 
Error("Please specify a message");
    }

    
// make sure any supplied options take precedence over defaults
    
options = $.extend({}, defaultsoptions);

    if (!
options.buttons) {
      
options.buttons = {};
    }

    
// we only support Bootstrap's "static" and false backdrop args
    // supporting true would mean you could dismiss the dialog without
    // explicitly interacting with it
    
options.backdrop options.backdrop "static" false;

    
buttons options.buttons;

    
total getKeyLength(buttons);

    
each(buttons, function(keybuttonindex) {

      if ($.
isFunction(button)) {
        
// short form, assume value is our callback. Since button
        // isn't an object it isn't a reference either so re-assign it
        
button buttons[key] = {
          
callbackbutton
        
};
      }

      
// before any further checks make sure by now button is the correct type
      
if ($.type(button) !== "object") {
        throw new 
Error("button with key " key " must be an object");
      }

      if (!
button.label) {
        
// the lack of an explicit label means we'll assume the key is good enough
        
button.label key;
      }

      if (!
button.className) {
        if (
total <= && index === total-1) {
          
// always add a primary to the main option in a two-button dialog
          
button.className "btn-primary";
        } else {
          
button.className "btn-default";
        }
      }
    });

    return 
options;
  }

  
/**
   * map a flexible set of arguments into a single returned object
   * if args.length is already one just return it, otherwise
   * use the properties argument to map the unnamed args to
   * object properties
   * so in the latter case:
   * mapArguments(["foo", $.noop], ["message", "callback"])
   * -> { message: "foo", callback: $.noop }
   */
  
function mapArguments(argsproperties) {
    var 
argn args.length;
    var 
options = {};

    if (
argn || argn 2) {
      throw new 
Error("Invalid argument length");
    }

    if (
argn === || typeof args[0] === "string") {
      
options[properties[0]] = args[0];
      
options[properties[1]] = args[1];
    } else {
      
options args[0];
    }

    return 
options;
  }

  
/**
   * merge a set of default dialog options with user supplied arguments
   */
  
function mergeArguments(defaultsargsproperties) {
    return $.
extend(
      
// deep merge
      
true,
      
// ensure the target is an empty, unreferenced object
      
{},
      
// the base options object for this type of dialog (often just buttons)
      
defaults,
      
// args could be an object or array; if it's an array properties will
      // map it to a proper options object
      
mapArguments(
        
args,
        
properties
      
)
    );
  }

  
/**
   * this entry-level method makes heavy use of composition to take a simple
   * range of inputs and return valid options suitable for passing to bootbox.dialog
   */
  
function mergeDialogOptions(classNamelabelspropertiesargs) {
    
//  build up a base set of dialog properties
    
var baseOptions = {
      
className"bootbox-" className,
      
buttonscreateLabels.apply(nulllabels)
    };

    
// ensure the buttons properties generated, *after* merging
    // with user args are still valid against the supplied labels
    
return validateButtons(
      
// merge the generated base properties with user supplied arguments
      
mergeArguments(
        
baseOptions,
        
args,
        
// if args.length > 1, properties specify how each arg maps to an object key
        
properties
      
),
      
labels
    
);
  }

  
/**
   * from a given list of arguments return a suitable object of button labels
   * all this does is normalise the given labels and translate them where possible
   * e.g. "ok", "confirm" -> { ok: "OK, cancel: "Annuleren" }
   */
  
function createLabels() {
    var 
buttons = {};

    for (var 
0arguments.lengthji++) {
      var 
argument arguments[i];
      var 
key argument.toLowerCase();
      var 
value argument.toUpperCase();

      
buttons[key] = {
        
label_t(value)
      };
    }

    return 
buttons;
  }

  function 
validateButtons(optionsbuttons) {
    var 
allowedButtons = {};
    
each(buttons, function(keyvalue) {
      
allowedButtons[value] = true;
    });

    
each(options.buttons, function(key) {
      if (
allowedButtons[key] === undefined) {
        throw new 
Error("button key " key " is not allowed (options are " buttons.join("n") + ")");
      }
    });

    return 
options;
  }

  
exports.alert = function() {
    var 
options;

    
options mergeDialogOptions("alert", ["ok"], ["message""callback"], arguments);

    if (
options.callback && !$.isFunction(options.callback)) {
      throw new 
Error("alert requires callback property to be a function when provided");
    }

    
/**
     * overrides
     */
    
options.buttons.ok.callback options.onEscape = function() {
      if ($.
isFunction(options.callback)) {
        return 
options.callback();
      }
      return 
true;
    };

    return 
exports.dialog(options);
  };

  
exports.confirm = function() {
    var 
options;

    
options mergeDialogOptions("confirm", ["cancel""confirm"], ["message""callback"], arguments);

    
/**
     * overrides; undo anything the user tried to set they shouldn't have
     */
    
options.buttons.cancel.callback options.onEscape = function() {
      return 
options.callback(false);
    };

    
options.buttons.confirm.callback = function() {
      return 
options.callback(true);
    };

    
// confirm specific validation
    
if (!$.isFunction(options.callback)) {
      throw new 
Error("confirm requires a callback");
    }

    return 
exports.dialog(options);
  };

  
exports.prompt = function() {
    var 
options;
    var 
defaults;
    var 
dialog;
    var 
form;
    var 
input;
    var 
shouldShow;
    var 
inputOptions;

    
// we have to create our form first otherwise
    // its value is undefined when gearing up our options
    // @TODO this could be solved by allowing message to
    // be a function instead...
    
form = $(templates.form);

    
// prompt defaults are more complex than others in that
    // users can override more defaults
    // @TODO I don't like that prompt has to do a lot of heavy
    // lifting which mergeDialogOptions can *almost* support already
    // just because of 'value' and 'inputType' - can we refactor?
    
defaults = {
      
className"bootbox-prompt",
      
buttonscreateLabels("cancel""confirm"),
      
value"",
      
inputType"text"
    
};

    
options validateButtons(
      
mergeArguments(defaultsarguments, ["title""callback"]),
      [
"cancel""confirm"]
    );

    
// capture the user's show value; we always set this to false before
    // spawning the dialog to give us a chance to attach some handlers to
    // it, but we need to make sure we respect a preference not to show it
    
shouldShow = (options.show === undefined) ? true options.show;

    
// check if the browser supports the option.inputType
    
var html5inputs = ["date","time","number"];
    var 
document.createElement("input");
    
i.setAttribute("type"options.inputType);
    if(
html5inputs[options.inputType]){
      
options.inputType i.type;
    }

    
/**
     * overrides; undo anything the user tried to set they shouldn't have
     */
    
options.message form;

    
options.buttons.cancel.callback options.onEscape = function() {
      return 
options.callback(null);
    };

    
options.buttons.confirm.callback = function() {
      var 
value;

      switch (
options.inputType) {
        case 
"text":
        case 
"textarea":
        case 
"email":
        case 
"select":
        case 
"date":
        case 
"time":
        case 
"number":
        case 
"password":
          
value input.val();
          break;

        case 
"checkbox":
          var 
checkedItems input.find("input:checked");

          
// we assume that checkboxes are always multiple,
          // hence we default to an empty array
          
value = [];

          
each(checkedItems, function(_item) {
            
value.push($(item).val());
          });
          break;
      }

      return 
options.callback(value);
    };

    
options.show false;

    
// prompt specific validation
    
if (!options.title) {
      throw new 
Error("prompt requires a title");
    }

    if (!$.
isFunction(options.callback)) {
      throw new 
Error("prompt requires a callback");
    }

    if (!
templates.inputs[options.inputType]) {
      throw new 
Error("invalid prompt type");
    }

    
// create the input based on the supplied type
    
input = $(templates.inputs[options.inputType]);

    switch (
options.inputType) {
      case 
"text":
      case 
"textarea":
      case 
"email":
      case 
"date":
      case 
"time":
      case 
"number":
      case 
"password":
        
input.val(options.value);
        break;

      case 
"select":
        var 
groups = {};
        
inputOptions options.inputOptions || [];

        if (!
inputOptions.length) {
          throw new 
Error("prompt with select requires options");
        }

        
each(inputOptions, function(_option) {

          
// assume the element to attach to is the input...
          
var elem input;

          if (
option.value === undefined || option.text === undefined) {
            throw new 
Error("given options in wrong format");
          }


          
// ... but override that element if this option sits in a group

          
if (option.group) {
            
// initialise group if necessary
            
if (!groups[option.group]) {
              
groups[option.group] = $("<optgroup/>").attr("label"option.group);
            }

            
elem groups[option.group];
          }

          
elem.append("<option value='" option.value "'>" option.text "</option>");
        });

        
each(groups, function(_group) {
          
input.append(group);
        });

        
// safe to set a select's value as per a normal input
        
input.val(options.value);
        break;

      case 
"checkbox":
        var 
values   = $.isArray(options.value) ? options.value : [options.value];
        
inputOptions options.inputOptions || [];

        if (!
inputOptions.length) {
          throw new 
Error("prompt with checkbox requires options");
        }

        if (!
inputOptions[0].value || !inputOptions[0].text) {
          throw new 
Error("given options in wrong format");
        }

        
// checkboxes have to nest within a containing element, so
        // they break the rules a bit and we end up re-assigning
        // our 'input' element to this container instead
        
input = $("<div/>");

        
each(inputOptions, function(_option) {
          var 
checkbox = $(templates.inputs[options.inputType]);

          
checkbox.find("input").attr("value"option.value);
          
checkbox.find("label").append(option.text);

          
// we've ensured values is an array so we can always iterate over it
          
each(values, function(_value) {
            if (
value === option.value) {
              
checkbox.find("input").prop("checked"true);
            }
          });

          
input.append(checkbox);
        });
        break;
    }

    if (
options.placeholder) {
      
input.attr("placeholder"options.placeholder);
    }

    if(
options.pattern){
      
input.attr("pattern"options.pattern);
    }

    
// now place it in our form
    
form.append(input);

    
form.on("submit", function(e) {
      
e.preventDefault();
      
// Fix for SammyJS (or similar JS routing library) hijacking the form post.
      
e.stopPropagation();
      
// @TODO can we actually click *the* button object instead?
      // e.g. buttons.confirm.click() or similar
      
dialog.find(".btn-primary").click();
    });

    
dialog exports.dialog(options);

    
// clear the existing handler focusing the submit button...
    
dialog.off("shown.bs.modal");

    
// ...and replace it with one focusing our input, if possible
    
dialog.on("shown.bs.modal", function() {
      
input.focus();
    });

    if (
shouldShow === true) {
      
dialog.modal("show");
    }

    return 
dialog;
  };

  
exports.dialog = function(options) {
    
options sanitize(options);

    var 
dialog = $(templates.dialog);
    var 
innerDialog dialog.find(".modal-dialog");
    var 
body dialog.find(".modal-body");
    var 
buttons options.buttons;
    var 
buttonStr "";
    var 
callbacks = {
      
onEscapeoptions.onEscape
    
};

    
each(buttons, function(keybutton) {

      
// @TODO I don't like this string appending to itself; bit dirty. Needs reworking
      // can we just build up button elements instead? slower but neater. Then button
      // can just become a template too
      
buttonStr += "<button data-bb-handler='" key "' type='button' class='btn " button.className "'>" button.label "</button>";
      
callbacks[key] = button.callback;
    });

    
body.find(".bootbox-body").html(options.message);

    if (
options.animate === true) {
      
dialog.addClass("fade");
    }

    if (
options.className) {
      
dialog.addClass(options.className);
    }

    if (
options.size === "large") {
      
innerDialog.addClass("modal-lg");
    }

    if (
options.size === "small") {
      
innerDialog.addClass("modal-sm");
    }

    if (
options.title) {
      
body.before(templates.header);
    }

    if (
options.closeButton) {
      var 
closeButton = $(templates.closeButton);

      if (
options.title) {
        
dialog.find(".modal-header").prepend(closeButton);
      } else {
        
closeButton.css("margin-top""-10px").prependTo(body);
      }
    }

    if (
options.title) {
      
dialog.find(".modal-title").html(options.title);
    }

    if (
buttonStr.length) {
      
body.after(templates.footer);
      
dialog.find(".modal-footer").html(buttonStr);
    }


    
/**
     * Bootstrap event listeners; used handle extra
     * setup & teardown required after the underlying
     * modal has performed certain actions
     */

    
dialog.on("hidden.bs.modal", function(e) {
      
// ensure we don't accidentally intercept hidden events triggered
      // by children of the current dialog. We shouldn't anymore now BS
      // namespaces its events; but still worth doing
      
if (e.target === this) {
        
dialog.remove();
      }
    });

    
/*
    dialog.on("show.bs.modal", function() {
      // sadly this doesn't work; show is called *just* before
      // the backdrop is added so we'd need a setTimeout hack or
      // otherwise... leaving in as would be nice
      if (options.backdrop) {
        dialog.next(".modal-backdrop").addClass("bootbox-backdrop");
      }
    });
    */

    
dialog.on("shown.bs.modal", function() {
      
dialog.find(".btn-primary:first").focus();
    });

    
/**
     * Bootbox event listeners; experimental and may not last
     * just an attempt to decouple some behaviours from their
     * respective triggers
     */

    
dialog.on("escape.close.bb", function(e) {
      if (
callbacks.onEscape) {
        
processCallback(edialogcallbacks.onEscape);
      }
    });

    
/**
     * Standard jQuery event listeners; used to handle user
     * interaction with our dialog
     */

    
dialog.on("click"".modal-footer button", function(e) {
      var 
callbackKey = $(this).data("bb-handler");

      
processCallback(edialogcallbacks[callbackKey]);

    });

    
dialog.on("click"".bootbox-close-button", function(e) {
      
// onEscape might be falsy but that's fine; the fact is
      // if the user has managed to click the close button we
      // have to close the dialog, callback or not
      
processCallback(edialogcallbacks.onEscape);
    });

    
dialog.on("keyup", function(e) {
      if (
e.which === 27) {
        
dialog.trigger("escape.close.bb");
      }
    });

    
// the remainder of this method simply deals with adding our
    // dialogent to the DOM, augmenting it with Bootstrap's modal
    // functionality and then giving the resulting object back
    // to our caller

    
$(options.container).append(dialog);

    
dialog.modal({
      
backdropoptions.backdrop,
      
keyboardfalse,
      
showfalse
    
});

    if (
options.show) {
      
dialog.modal("show");
    }

    
// @TODO should we return the raw element here or should
    // we wrap it in an object on which we can expose some neater
    // methods, e.g. var d = bootbox.alert(); d.hide(); instead
    // of d.modal("hide");

   /*
    function BBDialog(elem) {
      this.elem = elem;
    }

    BBDialog.prototype = {
      hide: function() {
        return this.elem.modal("hide");
      },
      show: function() {
        return this.elem.modal("show");
      }
    };
    */

    
return dialog;

  };

  
exports.setDefaults = function() {
    var 
values = {};

    if (
arguments.length === 2) {
      
// allow passing of single key/value...
      
values[arguments[0]] = arguments[1];
    } else {
      
// ... and as an object too
      
values arguments[0];
    }

    $.
extend(defaultsvalues);
  };

  
exports.hideAll = function() {
    $(
".bootbox").modal("hide");
  };


  
/**
   * standard locales. Please add more according to ISO 639-1 standard. Multiple language variants are
   * unlikely to be required. If this gets too large it can be split out into separate JS files.
   */
  
var locales = {
    
br : {
      
OK      "OK",
      
CANCEL  "Cancelar",
      
CONFIRM "Sim"
    
},
    
da : {
      
OK      "OK",
      
CANCEL  "Annuller",
      
CONFIRM "Accepter"
    
},
    
de : {
      
OK      "OK",
      
CANCEL  "Abbrechen",
      
CONFIRM "Akzeptieren"
    
},
    
en : {
      
OK      "OK",
      
CANCEL  "Cancel",
      
CONFIRM "OK"
    
},
    
es : {
      
OK      "OK",
      
CANCEL  "Cancelar",
      
CONFIRM "Aceptar"
    
},
    
fi : {
      
OK      "OK",
      
CANCEL  "Peruuta",
      
CONFIRM "OK"
    
},
    
fr : {
      
OK      "OK",
      
CANCEL  "Annuler",
      
CONFIRM "D'accord"
    
},
    
he : {
      
OK      "אישור",
      
CANCEL  "ביטול",
      
CONFIRM "אישור"
    
},
    
it : {
      
OK      "OK",
      
CANCEL  "Annulla",
      
CONFIRM "Conferma"
    
},
    
lt : {
      
OK      "Gerai",
      
CANCEL  "AtÅ¡aukti",
      
CONFIRM "Patvirtinti"
    
},
    
lv : {
      
OK      "Labi",
      
CANCEL  "Atcelt",
      
CONFIRM "Apstiprināt"
    
},
    
nl : {
      
OK      "OK",
      
CANCEL  "Annuleren",
      
CONFIRM "Accepteren"
    
},
    
no : {
      
OK      "OK",
      
CANCEL  "Avbryt",
      
CONFIRM "OK"
    
},
    
pl : {
      
OK      "OK",
      
CANCEL  "Anuluj",
      
CONFIRM "Potwierdź"
    
},
    
ru : {
      
OK      "OK",
      
CANCEL  "Отмена",
      
CONFIRM "ОК"
    
},
    
sv : {
      
OK      "OK",
      
CANCEL  "Avbryt",
      
CONFIRM "OK"
    
},
    
tr : {
      
OK      "Tamam",
      
CANCEL  "İptal",
      
CONFIRM "Onayla"
    
},
    
zh_CN : {
      
OK      "OK",
      
CANCEL  "取消",
      
CONFIRM "确认"
    
},
    
zh_TW : {
      
OK      "OK",
      
CANCEL  "取消",
      
CONFIRM "確認"
    
}
  };

  
exports.init = function(_$) {
    return 
init(_$ || $);
  };

  return 
exports;
}));
?>
Онлайн: 2
Реклама