diff --git a/.eslintrc.json b/.eslintrc.json index 41a3d51898c..862dd126060 100644 --- a/.eslintrc.json +++ b/.eslintrc.json @@ -4,6 +4,7 @@ "globals": { }, "rules": { + "indent": ["error", 2], "no-extra-semi": "warn", "eol-last": ["error", "always"] } diff --git a/openlibrary/plugins/openlibrary/js/account.js b/openlibrary/plugins/openlibrary/js/account.js index 2d5c9d836bc..27ebccc9f14 100644 --- a/openlibrary/plugins/openlibrary/js/account.js +++ b/openlibrary/plugins/openlibrary/js/account.js @@ -1,54 +1,54 @@ function setup_account_create() { - $("#signup").validate({ - invalidHandler: function(form, validator) { - var errors = validator.numberOfInvalids(); - if (errors) { - var message = (errors == 1 ? "Hang on... you missed 1 field. It's highlighted below." : "Hang on...you missed some fields.They 're highlighted below."); - $("div#contentMsg span").html(message); - $("div#contentMsg").show().fadeTo(3000, 1).slideUp(); - $("span.remind").css("font-weight", "700").css("text-decoration", "underline"); - } else { - $("div#contentMsg").hide(); - } - }, - errorClass: "invalid", - validClass: "success", - highlight: function(element, errorClass) { - $(element).addClass(errorClass); - $(element.form).find("label[for=" + element.id + "]") - .addClass(errorClass); - } - }); - $("#email").rules("add", { - required: true, - email: true, - messages: { - required: "", - email: "Are you sure that's an email address?" - } - }); - $("#username").rules("add", { - required: true, - minlength: 3, - maxlength: 20, - messages: { - required: "", - minlength: jQuery.format("This has to be at least {0} characters."), - maxlength: jQuery.format("Sorry! This can't exceed {0} characters.") - } - }); - $("#password").rules("add", { - required: true, - messages: { - required: "" - } - }); + $("#signup").validate({ + invalidHandler: function(form, validator) { + var errors = validator.numberOfInvalids(); + if (errors) { + var message = (errors == 1 ? "Hang on... you missed 1 field. It's highlighted below." : "Hang on...you missed some fields.They 're highlighted below."); + $("div#contentMsg span").html(message); + $("div#contentMsg").show().fadeTo(3000, 1).slideUp(); + $("span.remind").css("font-weight", "700").css("text-decoration", "underline"); + } else { + $("div#contentMsg").hide(); + } + }, + errorClass: "invalid", + validClass: "success", + highlight: function(element, errorClass) { + $(element).addClass(errorClass); + $(element.form).find("label[for=" + element.id + "]") + .addClass(errorClass); + } + }); + $("#email").rules("add", { + required: true, + email: true, + messages: { + required: "", + email: "Are you sure that's an email address?" + } + }); + $("#username").rules("add", { + required: true, + minlength: 3, + maxlength: 20, + messages: { + required: "", + minlength: jQuery.format("This has to be at least {0} characters."), + maxlength: jQuery.format("Sorry! This can't exceed {0} characters.") + } + }); + $("#password").rules("add", { + required: true, + messages: { + required: "" + } + }); - // CHECK USERNAME AVAILABILITY - $('#usernameLoading').hide(); - $('#emailLoading').hide(); + // CHECK USERNAME AVAILABILITY + $('#usernameLoading').hide(); + $('#emailLoading').hide(); -}; +} /* function finishAjaxUsername(id, response) { @@ -83,172 +83,172 @@ function setup_account_create() { //RECAPTCHA var RecaptchaOptions = { - theme: 'custom', - tabindex: 4, - custom_theme_widget: 'recaptcha_widget' + theme: 'custom', + tabindex: 4, + custom_theme_widget: 'recaptcha_widget' }; function validateEmail() { - $("form.email").validate({ - invalidHandler: function(form, validator) { - var errors = validator.numberOfInvalids(); - if (errors) { - var message = errors == 1 ? 'Hang on... You forgot to provide an updated email address.' : 'Hang on... You forgot to provide an updated email address.'; - $("div#contentMsg span").html(message); - $("div#contentMsg").show().fadeTo(3000, 1).slideUp(); - $("span.remind").css("font-weight", "700").css("text-decoration", "underline"); - } else { - $("div#contentMsg").hide(); - } - }, - errorClass: "invalid", - validClass: "success", - highlight: function(element, errorClass) { - $(element).addClass(errorClass); - $(element.form).find("label[for=" + element.id + "]") - .addClass(errorClass); - } - }); - $("#email").rules("add", { - required: true, - email: true, - messages: { - required: "", - email: "Are you sure that's an email address?" - } - }); -}; + $("form.email").validate({ + invalidHandler: function(form, validator) { + var errors = validator.numberOfInvalids(); + if (errors) { + var message = errors == 1 ? 'Hang on... You forgot to provide an updated email address.' : 'Hang on... You forgot to provide an updated email address.'; + $("div#contentMsg span").html(message); + $("div#contentMsg").show().fadeTo(3000, 1).slideUp(); + $("span.remind").css("font-weight", "700").css("text-decoration", "underline"); + } else { + $("div#contentMsg").hide(); + } + }, + errorClass: "invalid", + validClass: "success", + highlight: function(element, errorClass) { + $(element).addClass(errorClass); + $(element.form).find("label[for=" + element.id + "]") + .addClass(errorClass); + } + }); + $("#email").rules("add", { + required: true, + email: true, + messages: { + required: "", + email: "Are you sure that's an email address?" + } + }); +} function validateDelete() { - $("form.delete").validate({ - invalidHandler: function(form, validator) { - var errors = validator.numberOfInvalids(); - if (errors) { - var message = (errors == 1 ? 'You need to click the box to delete your account.': 'You need to click the box to delete your account.'); - $("div#contentMsg span").html(message); - $("div#contentMsg").show().fadeTo(3000, 1).slideUp(); - $("span.remind").css("font-weight", "700").css("text-decoration", "underline"); - } else { - $("div#contentMsg").hide(); - } - }, - errorClass: "invalid", - validClass: "success", - highlight: function(element, errorClass) { - $(element).addClass(errorClass); - $(element.form).find("label[for=" + element.id + "]") - .addClass(errorClass); - } - }); - $("#delete").rules("add", { - required: true, - messages: { - required: "" - } - }); -}; + $("form.delete").validate({ + invalidHandler: function(form, validator) { + var errors = validator.numberOfInvalids(); + if (errors) { + var message = (errors == 1 ? 'You need to click the box to delete your account.': 'You need to click the box to delete your account.'); + $("div#contentMsg span").html(message); + $("div#contentMsg").show().fadeTo(3000, 1).slideUp(); + $("span.remind").css("font-weight", "700").css("text-decoration", "underline"); + } else { + $("div#contentMsg").hide(); + } + }, + errorClass: "invalid", + validClass: "success", + highlight: function(element, errorClass) { + $(element).addClass(errorClass); + $(element.form).find("label[for=" + element.id + "]") + .addClass(errorClass); + } + }); + $("#delete").rules("add", { + required: true, + messages: { + required: "" + } + }); +} function validateLogin() { - $(".login").validate({ - invalidHandler: function(form, validator) { - var errors = validator.numberOfInvalids(); - if (errors) { - var message = (errors == 1? "Hang on... you missed 1 field. It's highlighted below.": "Hang on...you missed both fields.They 're highlighted below."); - $("div#contentMsg span").html(message); - $("div#contentMsg").show().fadeTo(3000, 1).slideUp(); - $("span.remind").css("font-weight", "700").css("text-decoration", "underline"); - } else { - $("div#contentMsg").hide(); - } - }, - errorClass: "invalid", - validClass: "success", - highlight: function(element, errorClass) { - $(element).addClass(errorClass); - $(element.form).find("label[for=" + element.id + "]") - .addClass(errorClass); - } - }); - $("#username").rules("add", { - required: true, - minlength: 3, - maxlength: 20, - messages: { - required: "", - minlength: jQuery.format("This has to be at least {0} characters."), - maxlength: jQuery.format("Sorry! This can't exceed {0} characters.") - } - }); - $("#password").rules("add", { - required: true, - messages: { - required: "" - } - }); -}; + $(".login").validate({ + invalidHandler: function(form, validator) { + var errors = validator.numberOfInvalids(); + if (errors) { + var message = (errors == 1? "Hang on... you missed 1 field. It's highlighted below.": "Hang on...you missed both fields.They 're highlighted below."); + $("div#contentMsg span").html(message); + $("div#contentMsg").show().fadeTo(3000, 1).slideUp(); + $("span.remind").css("font-weight", "700").css("text-decoration", "underline"); + } else { + $("div#contentMsg").hide(); + } + }, + errorClass: "invalid", + validClass: "success", + highlight: function(element, errorClass) { + $(element).addClass(errorClass); + $(element.form).find("label[for=" + element.id + "]") + .addClass(errorClass); + } + }); + $("#username").rules("add", { + required: true, + minlength: 3, + maxlength: 20, + messages: { + required: "", + minlength: jQuery.format("This has to be at least {0} characters."), + maxlength: jQuery.format("Sorry! This can't exceed {0} characters.") + } + }); + $("#password").rules("add", { + required: true, + messages: { + required: "" + } + }); +} function validatePassword() { - $("form.password").validate({ - invalidHandler: function(form, validator) { - var errors = validator.numberOfInvalids(); - if (errors) { - var message = (errors == 1? 'Hang on... you missed a field.': 'Hang on... to change your password, we need your current and your new one.'); - $("div#contentMsg span").html(message); - $("div#contentMsg").show().fadeTo(3000, 1).slideUp(); - $("span.remind").css("font-weight", "700").css("text-decoration", "underline"); - } else { - $("div#contentMsg").hide(); - } - }, - errorClass: "invalid", - validClass: "success", - highlight: function(element, errorClass) { - $(element).addClass(errorClass); - $(element.form).find("label[for=" + element.id + "]") - .addClass(errorClass); - } - }); - $("#password").rules("add", { - required: true, - messages: { - required: "." - } - }); - $("#new_password").rules("add", { - required: true, - messages: { - required: "" - } - }); -}; + $("form.password").validate({ + invalidHandler: function(form, validator) { + var errors = validator.numberOfInvalids(); + if (errors) { + var message = (errors == 1? 'Hang on... you missed a field.': 'Hang on... to change your password, we need your current and your new one.'); + $("div#contentMsg span").html(message); + $("div#contentMsg").show().fadeTo(3000, 1).slideUp(); + $("span.remind").css("font-weight", "700").css("text-decoration", "underline"); + } else { + $("div#contentMsg").hide(); + } + }, + errorClass: "invalid", + validClass: "success", + highlight: function(element, errorClass) { + $(element).addClass(errorClass); + $(element.form).find("label[for=" + element.id + "]") + .addClass(errorClass); + } + }); + $("#password").rules("add", { + required: true, + messages: { + required: "." + } + }); + $("#new_password").rules("add", { + required: true, + messages: { + required: "" + } + }); +} function validateReminder() { - $("form.reminder").validate({ - invalidHandler: function(form, validator) { - var errors = validator.numberOfInvalids(); - if (errors) { - var message = (errors == 1 ? 'Hang on... to change your password, we need your email address.' : 'Hang on... to change your password, we need your email address.'); - $("div#contentMsg span").html(message); - $("div#contentMsg").show().fadeTo(3000, 1).slideUp(); - $("span.remind").css("font-weight", "700").css("text-decoration", "underline"); - } else { - $("div#contentMsg").hide(); - } - }, - errorClass: "invalid", - validClass: "success", - highlight: function(element, errorClass) { - $(element).addClass(errorClass); - $(element.form).find("label[for=" + element.id + "]") - .addClass(errorClass); - } - }); - $("#email").rules("add", { - required: true, - email: true, - messages: { - required: "", - email: "Are you sure that's an email address?" - } - }); -}; + $("form.reminder").validate({ + invalidHandler: function(form, validator) { + var errors = validator.numberOfInvalids(); + if (errors) { + var message = (errors == 1 ? 'Hang on... to change your password, we need your email address.' : 'Hang on... to change your password, we need your email address.'); + $("div#contentMsg span").html(message); + $("div#contentMsg").show().fadeTo(3000, 1).slideUp(); + $("span.remind").css("font-weight", "700").css("text-decoration", "underline"); + } else { + $("div#contentMsg").hide(); + } + }, + errorClass: "invalid", + validClass: "success", + highlight: function(element, errorClass) { + $(element).addClass(errorClass); + $(element.form).find("label[for=" + element.id + "]") + .addClass(errorClass); + } + }); + $("#email").rules("add", { + required: true, + email: true, + messages: { + required: "", + email: "Are you sure that's an email address?" + } + }); +} diff --git a/openlibrary/plugins/openlibrary/js/add_new_field.js b/openlibrary/plugins/openlibrary/js/add_new_field.js index 197016dcf38..96fa7150dd3 100644 --- a/openlibrary/plugins/openlibrary/js/add_new_field.js +++ b/openlibrary/plugins/openlibrary/js/add_new_field.js @@ -14,86 +14,86 @@ * - On cancel/close: * - value of the select is set to "" to select "select xxx" */ -;(function($){ - $.fn.add_new_field = function(_options) { - $(this).each(function() { - var options = _options || {href: "#" + this.id + "-popup"}; - var $this = $(this); +(function($){ + $.fn.add_new_field = function(_options) { + $(this).each(function() { + var options = _options || {href: "#" + this.id + "-popup"}; + var $this = $(this); - var $json = $('') - .attr("name", this.id + "-json") - .addClass("repeat-ignore") // tell repeat plugin to ignore this input - .val("[]") - .insertBefore($this); + var $json = $('') + .attr("name", this.id + "-json") + .addClass("repeat-ignore") // tell repeat plugin to ignore this input + .val("[]") + .insertBefore($this); - $this.change(function(){ - var value = $this.val(); - if (value == "__add__") { - if (options.onshow) { - options.onshow.apply($this, []); - } - $.fn.colorbox({ - inline: true, - opacity: "0.5", - href: options.href, - open: true - }); - } - }); + $this.change(function(){ + var value = $this.val(); + if (value == "__add__") { + if (options.onshow) { + options.onshow.apply($this, []); + } + $.fn.colorbox({ + inline: true, + opacity: "0.5", + href: options.href, + open: true + }); + } + }); - // handle cancel - $(options.href).bind("cbox_closed", function() { + // handle cancel + $(options.href).bind("cbox_closed", function() { - if ($this.val() == "__add__") { - $this.val(""); - $this.focus(); - } - if (options.cancel) { - options.cancel(); - } - }); + if ($this.val() == "__add__") { + $this.val(""); + $this.focus(); + } + if (options.cancel) { + options.cancel(); + } + }); - // handle submit - $("form:first", $(options.href)).submit(function(event) { - event.preventDefault(); + // handle submit + $("form:first", $(options.href)).submit(function(event) { + event.preventDefault(); - // extract data - var array = $(this).serializeArray(); - var d = {}; + // extract data + var array = $(this).serializeArray(); + var d = {}; - for (var i in array) { - d[array[i].name] = $.trim(array[i].value); - } + for (var i in array) { + d[array[i].name] = $.trim(array[i].value); + } - // validate - if (options.validate && options.validate.apply($this, [d]) == false) { - return; - } + // validate + if (options.validate && options.validate.apply($this, [d]) == false) { + return; + } - // close popup - $.fn.colorbox.close(); + // close popup + $.fn.colorbox.close(); - // add new option - $("") - .html(d.label || d.value) - .attr("value", d.value) - .insertBefore($this.find("option:last").prev()) // insert before --- - .parent().val(d.value); + // add new option + $("") + .html(d.label || d.value) + .attr("value", d.value) + .insertBefore($this.find("option:last").prev()) // insert before --- + .parent().val(d.value); - // add JSON to hidden field - try { - var data = JSON.parse($json.val()); - } - catch (err) { - var data = []; - } - data.push(d); - $json.val(JSON.stringify(data)); + // add JSON to hidden field + try { + var data = JSON.parse($json.val()); + } + catch (err) { + var data = []; + } + data.push(d); + $json.val(JSON.stringify(data)); - // finally focus the next input field - $this.focusNextInputField(); - }); - return this; - }); - }; + // finally focus the next input field + $this.focusNextInputField(); + }); + return this; + }); + }; })(jQuery); diff --git a/openlibrary/plugins/openlibrary/js/autocomplete.js b/openlibrary/plugins/openlibrary/js/autocomplete.js index 0d9ac404907..359afeffc0c 100644 --- a/openlibrary/plugins/openlibrary/js/autocomplete.js +++ b/openlibrary/plugins/openlibrary/js/autocomplete.js @@ -1,7 +1,7 @@ // jquery plugins to provide author and language autocompletes. -;(function($) { - /** +(function($) { + /** * Some extra options for when creating an autocomplete input field * @typedef {Object} OpenLibraryAutocompleteOptions * @property{string} endpoint - url to hit for autocomplete results @@ -10,111 +10,111 @@ * a boolean. */ - /** + /** * @private * @param{HTMLInputElement} _this - input element that will become autocompleting. * @param{OpenLibraryAutocompleteOptions} ol_ac_opts * @param{Object} ac_opts - options passed to $.autocomplete; see that. */ - function setup_autocomplete(_this, ol_ac_opts, ac_opts) { - var default_ac_opts = { - autoFill: true, - mustMatch: true, - formatMatch: function(item) { return item.name; }, - parse: function(text) { - // in v2, text IS the JSON - var rows = typeof text === 'string' ? JSON.parse(text) : text; - var parsed = []; - for (var i=0; i < rows.length; i++) { - var row = rows[i]; - parsed.push({ - data: row, - value: row.name, - result: row.name - }); - } + function setup_autocomplete(_this, ol_ac_opts, ac_opts) { + var default_ac_opts = { + autoFill: true, + mustMatch: true, + formatMatch: function(item) { return item.name; }, + parse: function(text) { + // in v2, text IS the JSON + var rows = typeof text === 'string' ? JSON.parse(text) : text; + var parsed = []; + for (var i=0; i < rows.length; i++) { + var row = rows[i]; + parsed.push({ + data: row, + value: row.name, + result: row.name + }); + } - // XXX: this won't work when _this is multiple values (like $("input")) - var query = $(_this).val(); - if (ol_ac_opts.addnew && ol_ac_opts.addnew(query)) { - parsed = parsed.slice(0, ac_opts.max - 1); - parsed.push({ - data: {name: query, key: "__new__"}, - value: query, - result: query - }); - } - return parsed; - }, - }; + // XXX: this won't work when _this is multiple values (like $("input")) + var query = $(_this).val(); + if (ol_ac_opts.addnew && ol_ac_opts.addnew(query)) { + parsed = parsed.slice(0, ac_opts.max - 1); + parsed.push({ + data: {name: query, key: "__new__"}, + value: query, + result: query + }); + } + return parsed; + }, + }; - $(_this) - .autocomplete(ol_ac_opts.endpoint, $.extend(default_ac_opts, ac_opts)) - .result(function(event, item) { - $("#" + this.id + "-key").val(item.key); - var $this = $(this); + $(_this) + .autocomplete(ol_ac_opts.endpoint, $.extend(default_ac_opts, ac_opts)) + .result(function(event, item) { + $("#" + this.id + "-key").val(item.key); + var $this = $(this); - //adding class directly is not working when tab is pressed. setTimeout seems to be working! - setTimeout(function() { - $this.addClass("accept"); - }, 0); - }) - .nomatch(function(){ - $("#" + this.id + "-key").val(""); - $(this).addClass("reject"); - }) - .keypress(function() { - $(this).removeClass("accept").removeClass("reject"); - }); - } + //adding class directly is not working when tab is pressed. setTimeout seems to be working! + setTimeout(function() { + $this.addClass("accept"); + }, 0); + }) + .nomatch(function(){ + $("#" + this.id + "-key").val(""); + $(this).addClass("reject"); + }) + .keypress(function() { + $(this).removeClass("accept").removeClass("reject"); + }); + } - /** + /** * @this HTMLElement - the element that contains the different inputs. * @param {string} autocomplete_selector - selector to find the input element use for autocomplete. * @param {Function} input_renderer - ((index, item) -> html_string) render the ith div.input. * @param {OpenLibraryAutocompleteOptions} ol_ac_opts * @param {Object} ac_opts - options given to override defaults of $.autocomplete; see that. */ - $.fn.setup_multi_input_autocomplete = function(autocomplete_selector, input_renderer, ol_ac_opts, ac_opts) { - var container = $(this); + $.fn.setup_multi_input_autocomplete = function(autocomplete_selector, input_renderer, ol_ac_opts, ac_opts) { + var container = $(this); - // first let's init any pre-existing inputs - container.find(autocomplete_selector).each(function() { - setup_autocomplete(this, ol_ac_opts, ac_opts); - }); + // first let's init any pre-existing inputs + container.find(autocomplete_selector).each(function() { + setup_autocomplete(this, ol_ac_opts, ac_opts); + }); - function update_visible() { - if (container.find("div.input").length > 1) { - container.find("a.remove").show(); - } - else { - container.find("a.remove").hide(); - } + function update_visible() { + if (container.find("div.input").length > 1) { + container.find("a.remove").show(); + } + else { + container.find("a.remove").hide(); + } - container.find("a.add:not(:last)").hide(); - container.find("a.add:last").show(); - } + container.find("a.add:not(:last)").hide(); + container.find("a.add:last").show(); + } - update_visible(); + update_visible(); - container.find("a.remove").live("click", function() { - if (container.find("div.input").length > 1) { - $(this).closest("div.input").remove(); - update_visible(); - } - }); + container.find("a.remove").live("click", function() { + if (container.find("div.input").length > 1) { + $(this).closest("div.input").remove(); + update_visible(); + } + }); - container.find("a.add").live("click", function(event) { - event.preventDefault(); + container.find("a.add").live("click", function(event) { + event.preventDefault(); - var next_index = container.find("div.input").length; - var new_input = $(input_renderer(next_index, {key:"", name: ""})); - container.append(new_input); - setup_autocomplete( - new_input.find(autocomplete_selector)[0], - ol_ac_opts, - ac_opts); - update_visible(); - }); - }; + var next_index = container.find("div.input").length; + var new_input = $(input_renderer(next_index, {key:"", name: ""})); + container.append(new_input); + setup_autocomplete( + new_input.find(autocomplete_selector)[0], + ol_ac_opts, + ac_opts); + update_visible(); + }); + }; })(jQuery); diff --git a/openlibrary/plugins/openlibrary/js/automatic.js b/openlibrary/plugins/openlibrary/js/automatic.js index 51ad123eb90..b7ca250a0bc 100644 --- a/openlibrary/plugins/openlibrary/js/automatic.js +++ b/openlibrary/plugins/openlibrary/js/automatic.js @@ -3,42 +3,42 @@ */ jQuery(function($) { - // close-popup - $("a.close-popup").click(function() { - $.fn.colorbox.close(); + // close-popup + $("a.close-popup").click(function() { + $.fn.colorbox.close(); + }); + + // wmd editor + $("textarea.markdown").wmd({ + helpLink: "/help/markdown", + helpHoverTitle: "Formatting Help", + helpTarget: "_new" + }); + + // tabs + var options = {}; + if($.support.opacity){ + options.fx = {"opacity": "toggle"}; + } + + if ($(".tabs:not(.ui-tabs)").tabs) { + $(".tabs:not(.ui-tabs)").tabs(options) + $(".tabs.autohash").bind("tabsselect", function(event, ui) { + document.location.hash = ui.panel.id; }); + } - // wmd editor - $("textarea.markdown").wmd({ - helpLink: "/help/markdown", - helpHoverTitle: "Formatting Help", - helpTarget: "_new" - }); - - // tabs - var options = {}; - if($.support.opacity){ - options.fx = {"opacity": "toggle"}; - } - - if ($(".tabs:not(.ui-tabs)").tabs) { - $(".tabs:not(.ui-tabs)").tabs(options) - $(".tabs.autohash").bind("tabsselect", function(event, ui) { - document.location.hash = ui.panel.id; - }); - } + // validate forms + $("form.validate").ol_validate(); - // validate forms - $("form.validate").ol_validate(); + // hide info flash messages + $(".flash-messages .info").fadeTo(3000, 1).slideUp(); - // hide info flash messages - $(".flash-messages .info").fadeTo(3000, 1).slideUp(); + // hide all images in .no-img + $(".no-img img").hide(); - // hide all images in .no-img - $(".no-img img").hide(); - - // disable save button after click - $("button[name='_save']").submit(function() { - $(this).attr("disabled", true); - }); + // disable save button after click + $("button[name='_save']").submit(function() { + $(this).attr("disabled", true); + }); }); diff --git a/openlibrary/plugins/openlibrary/js/availability.js b/openlibrary/plugins/openlibrary/js/availability.js index c6abc4b33b9..65dbc0e4167 100644 --- a/openlibrary/plugins/openlibrary/js/availability.js +++ b/openlibrary/plugins/openlibrary/js/availability.js @@ -19,241 +19,241 @@ var getAvailabilityV2, updateBookAvailability, updateWorkAvailability; $(function(){ - // pages still relying on legacy client-side availability checking - var whitelist = { - '^\/account\/books\/[^/]+': { // readinglog - filter: false - }, - '^\/authors\/[^/]+': { // authors - filter: true - }, - '^\/people\/[^/]+': { // lists - filter: false, - }, - '^\/stats/[^/]+': { - filter: false - } + // pages still relying on legacy client-side availability checking + var whitelist = { + '^\/account\/books\/[^/]+': { // readinglog + filter: false + }, + '^\/authors\/[^/]+': { // authors + filter: true + }, + '^\/people\/[^/]+': { // lists + filter: false, + }, + '^\/stats/[^/]+': { + filter: false } + } - getAvailabilityV2 = function(_type, _ids, callback) { - if (!_ids.length) { - return callback({}); - } - var url = '/availability/v2?type=' + _type; - $.ajax({ - url: url, - type: "POST", - data: JSON.stringify({ - "ids": _ids - }), - dataType: "json", - contentType: "application/json", - beforeSend: function(xhr) { - xhr.setRequestHeader("Content-Type", "application/json"); - xhr.setRequestHeader("Accept", "application/json"); - }, - success: function(result) { - return callback(result); - } - }); - }; + getAvailabilityV2 = function(_type, _ids, callback) { + if (!_ids.length) { + return callback({}); + } + var url = '/availability/v2?type=' + _type; + $.ajax({ + url: url, + type: "POST", + data: JSON.stringify({ + "ids": _ids + }), + dataType: "json", + contentType: "application/json", + beforeSend: function(xhr) { + xhr.setRequestHeader("Content-Type", "application/json"); + xhr.setRequestHeader("Accept", "application/json"); + }, + success: function(result) { + return callback(result); + } + }); + }; - /* + /* * Finds DOM elements for borrowable books (i.e. they have a * data-ocaid field and a data-key field) within the specified * scope of `selector` and updates the displayed borrow status * and ebook links to reflect correct statuses and available * copies. */ - updateBookAvailability = function(selector) { - selector = (selector || '') + '[data-ocaid]'; - var books = {}; // lets us keep track of which ocaids came from - // which book (i.e. edition or work). As we learn - // ocaids are available, we'll need a way to - // determine which edition or work this ocaid - // comes from. - var ocaids = []; // a full set of ocaids spanning all books - // which can be checked in a single request - // to the availability API. - $(selector).each(function(index, elem) { - var data_ocaid = $(elem).attr('data-ocaid'); - if(data_ocaid) { - var book_ocaids = data_ocaid.split(',') - .filter(function(book) { return book !== "" }); - var book_key = $(elem).attr('data-key'); + updateBookAvailability = function(selector) { + selector = (selector || '') + '[data-ocaid]'; + var books = {}; // lets us keep track of which ocaids came from + // which book (i.e. edition or work). As we learn + // ocaids are available, we'll need a way to + // determine which edition or work this ocaid + // comes from. + var ocaids = []; // a full set of ocaids spanning all books + // which can be checked in a single request + // to the availability API. + $(selector).each(function(index, elem) { + var data_ocaid = $(elem).attr('data-ocaid'); + if(data_ocaid) { + var book_ocaids = data_ocaid.split(',') + .filter(function(book) { return book !== "" }); + var book_key = $(elem).attr('data-key'); - if(book_ocaids.length) { - books[book_key] = book_ocaids; - Array.prototype.push.apply(ocaids, book_ocaids); - } + if(book_ocaids.length) { + books[book_key] = book_ocaids; + Array.prototype.push.apply(ocaids, book_ocaids); + } + } + }); + + getAvailabilityV2('identifier', ocaids, function(response) { + for (var book_ocaid in response) { + if (response[book_ocaid].status === "borrow_available") { + // check all the books on this page + for (var book_key in books) { + var book_ocaids = books[book_key]; + // check if available book_ocaid is in + // this book_key's book_ocaids + if (book_ocaids.indexOf(book_ocaid) > -1) { + // update icon, ocaid, and url (to ia:) + // should limit scope to `selector` ! XXX + $(selector + "[data-key=" + book_key + "]") + .attr("href", "/borrow/ia/" + book_ocaid); + $(selector + "[data-key=" + book_key + "]") + .addClass('borrow_available').addClass('cta-btn') + $(selector + "[data-key=" + book_key + "]") + .text('Borrow'); + // since we've found an available edition to + // represent this book, we can stop and remove + // book_ocaid from book_ocaids (one less book + // to check against). + delete books[book_key]; } - }); + } + } else if (response[book_ocaid].status === "borrow_unavailable"){ + for (var book_key in books) { + var book_ocaids = books[book_key]; + if (book_ocaids.indexOf(book_ocaid) > -1) { + $(selector + "[data-key=" + book_key + "]") + .attr('title', 'Join waitlist'); + $(selector + "[data-key=" + book_key + "]") + .addClass('borrow_unavailable').addClass('cta-btn'); + $(selector + "[data-key=" + book_key + "]") + .text('Join Waitlist'); + delete books[book_key]; + } + } + } else { + for (var book_key in books) { + var book_ocaids = books[book_key]; + if (book_ocaids.indexOf(book_ocaid) > -1) { - getAvailabilityV2('identifier', ocaids, function(response) { - for (var book_ocaid in response) { - if (response[book_ocaid].status === "borrow_available") { - // check all the books on this page - for (var book_key in books) { - var book_ocaids = books[book_key]; - // check if available book_ocaid is in - // this book_key's book_ocaids - if (book_ocaids.indexOf(book_ocaid) > -1) { - // update icon, ocaid, and url (to ia:) - // should limit scope to `selector` ! XXX - $(selector + "[data-key=" + book_key + "]") - .attr("href", "/borrow/ia/" + book_ocaid); - $(selector + "[data-key=" + book_key + "]") - .addClass('borrow_available').addClass('cta-btn') - $(selector + "[data-key=" + book_key + "]") - .text('Borrow'); - // since we've found an available edition to - // represent this book, we can stop and remove - // book_ocaid from book_ocaids (one less book - // to check against). - delete books[book_key]; - } - } - } else if (response[book_ocaid].status === "borrow_unavailable"){ - for (var book_key in books) { - var book_ocaids = books[book_key]; - if (book_ocaids.indexOf(book_ocaid) > -1) { - $(selector + "[data-key=" + book_key + "]") - .attr('title', 'Join waitlist'); - $(selector + "[data-key=" + book_key + "]") - .addClass('borrow_unavailable').addClass('cta-btn'); - $(selector + "[data-key=" + book_key + "]") - .text('Join Waitlist'); - delete books[book_key]; - } - } - } else { - for (var book_key in books) { - var book_ocaids = books[book_key]; - if (book_ocaids.indexOf(book_ocaid) > -1) { + $(selector + "[data-key=" + book_key + "]") + .attr('href', $(selector + "[data-key=" + book_key + "]").attr('data-key')) + $(selector + "[data-key=" + book_key + "]") + .attr('title', 'Check Availability'); + $(selector + "[data-key=" + book_key + "]") + .removeClass('borrow-link'); + $(selector + "[data-key=" + book_key + "]") + .addClass('check-book-availability').addClass('cta-btn'); + $(selector + "[data-key=" + book_key + "]") + .text('Check Availability'); + delete books[book_key]; + } + } + } + } + }); + }; - $(selector + "[data-key=" + book_key + "]") - .attr('href', $(selector + "[data-key=" + book_key + "]").attr('data-key')) - $(selector + "[data-key=" + book_key + "]") - .attr('title', 'Check Availability'); - $(selector + "[data-key=" + book_key + "]") - .removeClass('borrow-link'); - $(selector + "[data-key=" + book_key + "]") - .addClass('check-book-availability').addClass('cta-btn'); - $(selector + "[data-key=" + book_key + "]") - .text('Check Availability'); - delete books[book_key]; - } - } - } - }; - }); - }; + updateWorkAvailability = function() { - updateWorkAvailability = function() { + // Determine whether availability check necessary for page + var checkAvailability = false; + var filter = false; + for (var page in whitelist) { + if (window.location.pathname.match(page)) { + checkAvailability = true; + filter = whitelist[page].filter; + } + } + if(!checkAvailability) { + return; + } - // Determine whether availability check necessary for page - var checkAvailability = false; - var filter = false; - for (var page in whitelist) { - if (window.location.pathname.match(page)) { - checkAvailability = true; - filter = whitelist[page].filter; - } - } - if(!checkAvailability) { - return; - } + if (localStorage.getItem('mode') === "printdisabled") { + var daisies = $('.print-disabled-only'); + $.each(daisies, function() { + $(this).removeClass('hidden'); + }); + return; + } - if (localStorage.getItem('mode') === "printdisabled") { - var daisies = $('.print-disabled-only'); - $.each(daisies, function() { - $(this).removeClass('hidden'); - }); - return; - } + var editions = []; + var works = []; + var results = $('a.results'); + $.each(results, function(index, e) { + var href = $(e).attr('href'); + var _type_key_slug = href.split('/') + var _type = _type_key_slug[1]; + var key = _type_key_slug[2]; + if (_type === 'works') { + works.push(key); + } else if (_type === 'books') { + editions.push(key); + } + }); - var editions = []; - var works = []; - var results = $('a.results'); + getAvailabilityV2('openlibrary_edition', editions, function(editions_response) { + getAvailabilityV2('openlibrary_work', works, function(works_response) { + var response = {'books': editions_response, 'works': works_response}; $.each(results, function(index, e) { - var href = $(e).attr('href'); - var _type_key_slug = href.split('/') - var _type = _type_key_slug[1]; - var key = _type_key_slug[2]; - if (_type === 'works') { - works.push(key); - } else if (_type === 'books') { - editions.push(key); - } - }); + var href = $(e).attr('href'); + var _type_key_slug = href.split('/') + var _type = _type_key_slug[1]; + var key = _type_key_slug[2]; + if (response[_type]) { + var work = response[_type][key]; + var li = $(e).closest("li"); + var cta = li.find(".searchResultItemCTA-lending"); + var msg = ''; + var link = ''; + var annotation = ''; + var tag = 'a'; - getAvailabilityV2('openlibrary_edition', editions, function(editions_response) { - getAvailabilityV2('openlibrary_work', works, function(works_response) { - var response = {'books': editions_response, 'works': works_response}; - $.each(results, function(index, e) { - var href = $(e).attr('href'); - var _type_key_slug = href.split('/') - var _type = _type_key_slug[1]; - var key = _type_key_slug[2]; - if (response[_type]) { - var work = response[_type][key]; - var li = $(e).closest("li"); - var cta = li.find(".searchResultItemCTA-lending"); - var msg = ''; - var link = ''; - var annotation = ''; - var tag = 'a'; + var mode = filter ? localStorage.getItem('mode') : 'everything'; - var mode = filter ? localStorage.getItem('mode') : 'everything'; - - if (mode !== "printdisabled") { - if (work.status === 'error' || work.status === 'private') { - if (mode === "ebooks") { - li.remove(); - } - } else { - var cls = 'borrow_available borrow-link'; - link = ' href="/books/' + work.openlibrary_edition + '/x/borrow" '; + if (mode !== "printdisabled") { + if (work.status === 'error' || work.status === 'private') { + if (mode === "ebooks") { + li.remove(); + } + } else { + var cls = 'borrow_available borrow-link'; + link = ' href="/books/' + work.openlibrary_edition + '/x/borrow" '; - if (work.status === 'open') { - msg = 'Read'; - } else if (work.status === 'borrow_available') { - msg = 'Borrow'; - } else if (work.status === 'borrow_unavailable') { - tag = 'span'; - link = ''; - cls = work.status; - msg = '
'; + if (work.status === 'open') { + msg = 'Read'; + } else if (work.status === 'borrow_available') { + msg = 'Borrow'; + } else if (work.status === 'borrow_unavailable') { + tag = 'span'; + link = ''; + cls = work.status; + msg = ''; - } else { - msg += 'Join Waitlist'; - annotation = '