"];
+ // @see https://github.com/makeusabrew/bootbox/issues/46#issuecomment-8235302
+ // and https://github.com/twitter/bootstrap/issues/4474
+ // for an explanation of the inline overflow: hidden
+ // @see https://github.com/twitter/bootstrap/issues/4854
+ // for an explanation of tabIndex=-1
+
+ var parts = ["
"];
if (options['header']) {
var closeButton = '';
if (typeof options['headerCloseButton'] == 'undefined' || options['headerCloseButton']) {
- closeButton = "
×";
+ closeButton = "
×";
}
parts.push("");
@@ -429,7 +376,7 @@ var bootbox = window.bootbox || (function($) {
parts.push("
");
if (buttons) {
- parts.push("")
+ parts.push("");
}
parts.push("
");
@@ -443,69 +390,270 @@ var bootbox = window.bootbox || (function($) {
div.addClass("fade");
}
- // now we've built up the div properly we can inject the content whether it was a string or a jQuery object
- $(".modal-body", div).html(str);
+ var optionalClasses = (typeof options.classes === 'undefined') ? _classes : options.classes;
+ if (optionalClasses) {
+ div.addClass(optionalClasses);
+ }
- div.bind('hidden', function() {
+ // now we've built up the div properly we can inject the content whether it was a string or a jQuery object
+ div.find(".modal-body").html(str);
+
+ function onCancel(source) {
+ console.log('onCancel');
+ // for now source is unused, but it will be in future
+ var hideModal = null;
+ if (typeof options.onEscape === 'function') {
+ // @see https://github.com/makeusabrew/bootbox/issues/91
+ hideModal = options.onEscape();
+ }
+
+ if (hideModal !== false) {
+ div.modal('hide');
+ }
+ }
+
+ // hook into the modal's keyup trigger to check for the escape key
+ div.on('keyup.dismiss.modal', function(e) {
+ console.log('keyup.dismiss.modal');
+ // any truthy value passed to onEscape will dismiss the dialog
+ // as long as the onEscape function (if defined) doesn't prevent it
+ if (e.which === 27 && options.onEscape !== false) {
+ onCancel('escape');
+ }
+ });
+
+ // handle close buttons too
+ div.on('click', 'a.close', function(e) {
+ e.preventDefault();
+ onCancel('close');
+ });
+
+ // well, *if* we have a primary - give the first dom element focus
+ div.on('shown', function() {
+ div.find("a.btn-primary:first").focus();
+ });
+
+ div.on('hidden', function() {
div.remove();
});
- div.bind('hide', function() {
- if (hideSource == 'escape' &&
- typeof options.onEscape == 'function') {
- options.onEscape();
- }
- });
-
- // hook into the modal's keyup trigger to check for the escape key
- $(document).bind('keyup.modal', function ( e ) {
- if (e.which == 27) {
- hideSource = 'escape';
- }
- });
-
- // well, *if* we have a primary - give the last dom element (first displayed) focus
- div.bind('shown', function() {
- $("a.btn-primary:last", div).focus();
- });
-
// wire up button handlers
- div.on('click', '.modal-footer a, a.close', function(e) {
+ div.on('click', '.modal-footer a', function(e) {
+
var handler = $(this).data("handler"),
cb = callbacks[handler],
hideModal = null;
- if (typeof cb == 'function') {
- hideModal = cb();
+ // sort of @see https://github.com/makeusabrew/bootbox/pull/68 - heavily adapted
+ // if we've got a custom href attribute, all bets are off
+ if (typeof handler !== 'undefined' &&
+ typeof handlers[handler]['href'] !== 'undefined') {
+
+ return;
}
- if (hideModal !== false){
- e.preventDefault();
- hideSource = 'button';
+
+ e.preventDefault();
+
+ if (typeof cb === 'function') {
+ hideModal = cb(e);
+ }
+
+ // the only way hideModal *will* be false is if a callback exists and
+ // returns it as a value. in those situations, don't hide the dialog
+ // @see https://github.com/makeusabrew/bootbox/pull/25
+ if (hideModal !== false) {
div.modal("hide");
}
});
- if (options.keyboard == null) {
- options.keyboard = (typeof options.onEscape == 'function');
- }
-
+ // stick the modal right at the bottom of the main body out of the way
$("body").append(div);
div.modal({
- "backdrop" : options.backdrop || true,
- "keyboard" : options.keyboard
+ // unless explicitly overridden take whatever our default backdrop value is
+ backdrop : (typeof options.backdrop === 'undefined') ? _backdrop : options.backdrop,
+ // ignore bootstrap's keyboard options; we'll handle this ourselves (more fine-grained control)
+ keyboard : false,
+ // @ see https://github.com/makeusabrew/bootbox/issues/69
+ // we *never* want the modal to be shown before we can bind stuff to it
+ // this method can also take a 'show' option, but we'll only use that
+ // later if we need to
+ show : false
});
+ // @see https://github.com/makeusabrew/bootbox/issues/64
+ // @see https://github.com/makeusabrew/bootbox/issues/60
+ // ...caused by...
+ // @see https://github.com/twitter/bootstrap/issues/4781
+ div.on("show", function(e) {
+ $(document).off("focusin.modal");
+ });
+
+ if (typeof options.show === 'undefined' || options.show === true) {
+ div.modal("show");
+ }
+
return div;
- }
+ };
+
+ /**
+ * #modal is deprecated in v3; it can still be used but no guarantees are
+ * made - have never been truly convinced of its merit but perhaps just
+ * needs a tidyup and some TLC
+ */
+ that.modal = function(/*str, label, options*/) {
+ var str;
+ var label;
+ var options;
+
+ var defaultOptions = {
+ "onEscape": null,
+ "keyboard": true,
+ "backdrop": _backdrop
+ };
+
+ switch (arguments.length) {
+ case 1:
+ str = arguments[0];
+ break;
+ case 2:
+ str = arguments[0];
+ if (typeof arguments[1] == 'object') {
+ options = arguments[1];
+ } else {
+ label = arguments[1];
+ }
+ break;
+ case 3:
+ str = arguments[0];
+ label = arguments[1];
+ options = arguments[2];
+ break;
+ default:
+ throw new Error("Incorrect number of arguments: expected 1-3");
+ }
+
+ defaultOptions['header'] = label;
+
+ if (typeof options == 'object') {
+ options = $.extend(defaultOptions, options);
+ } else {
+ options = defaultOptions;
+ }
+
+ return that.dialog(str, [], options);
+ };
+
that.hideAll = function() {
$(".bootbox").modal("hide");
- }
+ };
that.animate = function(animate) {
_animate = animate;
+ };
+
+ that.backdrop = function(backdrop) {
+ _backdrop = backdrop;
+ };
+
+ that.classes = function(classes) {
+ _classes = classes;
+ };
+
+ /**
+ * private API
+ */
+
+ /**
+ * 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'
+ },
+ 'fr' : {
+ OK : 'OK',
+ CANCEL : 'Annuler',
+ CONFIRM : 'D\'accord'
+ },
+ 'it' : {
+ OK : 'OK',
+ CANCEL : 'Annulla',
+ CONFIRM : 'Conferma'
+ },
+ 'nl' : {
+ OK : 'OK',
+ CANCEL : 'Annuleren',
+ CONFIRM : 'Accepteren'
+ },
+ 'pl' : {
+ OK : 'OK',
+ CANCEL : 'Anuluj',
+ CONFIRM : 'Potwierdź'
+ },
+ 'ru' : {
+ OK : 'OK',
+ CANCEL : 'Отмена',
+ CONFIRM : 'Применить'
+ },
+ 'zh_CN' : {
+ OK : 'OK',
+ CANCEL : '取消',
+ CONFIRM : '确认'
+ },
+ 'zh_TW' : {
+ OK : 'OK',
+ CANCEL : '取消',
+ CONFIRM : '確認'
+ }
+ };
+
+ function _translate(str, locale) {
+ // we assume if no target locale is probided then we should take it from current setting
+ if (typeof locale === 'undefined') {
+ locale = _locale;
+ }
+ if (typeof _locales[locale][str] === 'string') {
+ return _locales[locale][str];
+ }
+
+ // if we couldn't find a lookup then try and fallback to a default translation
+
+ if (locale != _defaultLocale) {
+ return _translate(str, _defaultLocale);
+ }
+
+ // if we can't do anything then bail out with whatever string was passed in - last resort
+ return str;
}
return that;
-})( window.jQuery );
+
+}(document, window.jQuery));
+
+// @see https://github.com/makeusabrew/bootbox/issues/71
+window.bootbox = bootbox;
diff --git a/app/assets/stylesheets/application/modal.css.scss b/app/assets/stylesheets/application/modal.css.scss
index 2c927275797..877db2ab1a9 100644
--- a/app/assets/stylesheets/application/modal.css.scss
+++ b/app/assets/stylesheets/application/modal.css.scss
@@ -229,3 +229,34 @@
width: 550px;
}
}
+
+.reply-where-modal {
+ width: 260px;
+ margin-left: -130px;
+ .modal-footer {
+ .btn {
+ text-align: left;
+ font-size: 16px;
+ width: 200px;
+ margin-bottom: 10px;
+ display: block;
+ margin-left: 0;
+ .topic-title {
+ font-size: 12px;
+ font-weight: normal;
+ white-space: nowrap;
+ overflow: hidden;
+ text-overflow: ellipsis;
+ max-width: 185px;
+ }
+ &.btn-reply-here {
+ @include linear-gradient(#ddd, #ddd);
+ text-shadow: none;
+ color: $darkish_gray;
+ }
+ }
+ .cancel {
+ text-decoration: underline;
+ }
+ }
+}
diff --git a/config/locales/client.en.yml b/config/locales/client.en.yml
index a43c61e5abb..9b76b3a246a 100644
--- a/config/locales/client.en.yml
+++ b/config/locales/client.en.yml
@@ -388,7 +388,7 @@ en:
message: "Authenticating with Mozilla Persona (make sure pop up blockers are not enabled)"
composer:
- posting_not_on_topic: "You are replying to the topic \"{{title}}\", but you are currently viewing a different topic."
+ posting_not_on_topic: "Which topic do you want to reply to?"
saving_draft_tip: "saving"
saved_draft_tip: "saved"
saved_local_draft_tip: "saved locally"