1/* 2 3This file is part of the plugin Pay with Vipps and MobilePay for WooCommerce 4Copyright (c) 2019 WP-Hosting AS 5 6MIT License 7 8Copyright (c) 2019 WP-Hosting AS 9 10Permission is hereby granted, free of charge, to any person obtaining a copy 11of this software and associated documentation files (the "Software"), to deal 12in the Software without restriction, including without limitation the rights 13to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 14copies of the Software, and to permit persons to whom the Software is 15furnished to do so, subject to the following conditions: 16 17The above copyright notice and this permission notice shall be included in all 18copies or substantial portions of the Software. 19 20THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 21IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 22FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 23AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 24LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 25OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 26SOFTWARE. 27 28*/ 29 30// Hook vippsInit to woocommerce/product-collection render event. LP 29.11.2024 31// IOK 2026-01-14 available from woo 9.4 - so the buy now block will not be available until that version 32document.body.addEventListener('wc-blocks_product_list_rendered', 33 function (event) { 34 document.body.dispatchEvent(new Event('vippsInit')); 35 } 36); 37 38jQuery( document ).ready( function() { 39 40 // This is for WooCommerce Product Bundles, which potentially have *several* variant-products or configurable products, so 41 // the standard Woo hooks don't apply. Luckily, we have other, simpler events to use. 42 // For this to work, we also have to force the compat-mode thing on. IOK 2020-04-21 43 jQuery('.cart.bundle_data').on('woocommerce-product-bundle-hide', function (e, variant) { 44 jQuery('form .button.single-product.vipps-buy-now').removeClass('variation-found'); 45 jQuery('form .button.single-product.vipps-buy-now').attr('disabled','disabled'); 46 jQuery('form .button.single-product.vipps-buy-now').addClass('disabled'); 47 // We don't know why the button is hidden, so ensure we use compatibility-mode IOK 2020-04-21 48 jQuery('.button.single-product.vipps-buy-now').addClass('compat-mode'); 49 removeErrorMessages(); 50 }); 51 jQuery('.cart.bundle_data').on('woocommerce-product-bundle-show', function (e, variant) { 52 jQuery('form .button.single-product.vipps-buy-now').addClass('variation-found'); 53 jQuery('form .button.single-product.vipps-buy-now').removeAttr('disabled'); 54 jQuery('form .button.single-product.vipps-buy-now').removeClass('disabled'); 55 removeErrorMessages(); 56 }); 57 58 // Hooks for the 'buy now with vipps' button on product pages etc 59 jQuery('body').on('found_variation', function (e,variation) { 60 const form = jQuery(e.target); 61 const target = form.find(".button.single-product.vipps-buy-now.variable-product"); 62 63 var purchasable=true; 64 if ( ! variation.is_purchasable || ! variation.is_in_stock || ! variation.variation_is_visible ) { 65 purchasable = false; 66 } 67 target.addClass('variation-found'); 68 if (purchasable) { 69 target.removeAttr('disabled'); 70 target.removeClass('disabled'); 71 removeErrorMessages(); 72 } else { 73 target.attr('disabled','disabled'); 74 target.addClass('disabled'); 75 removeErrorMessages(); 76 } 77 }); 78 jQuery('body').on('reset_data', function (e) { 79 const form = jQuery(e.target) 80 const target = form.find(".button.single-product.vipps-buy-now.variable-product"); 81 target.removeClass('variation-found'); 82 target.attr('disabled','disabled'); 83 target.addClass('disabled'); 84 removeErrorMessages(); 85 }); 86 // If this is triggered, somebody just loaded a variation form, so we need to redo the button init scripts 87 jQuery('body').on('wc_variation_form', function () { 88 vippsInit(); 89 }); 90 // Allow other guys to do this too 91 jQuery('body').on('vippsInit', function () { 92 vippsInit(); 93 }); 94 95 96 // Using ajax, get a session and a key and redirect to the "buy single product using express checkout" page. 97 function buySingleProduct (event) { 98 event.preventDefault(); 99 100 var element = jQuery(this); 101 if (jQuery('body').hasClass('processing')) return; // Trying to stop doublecclickers. IOK 2018-09-27 102 103 if (jQuery(element).hasClass('disabled')) { 104 if (typeof wc_add_to_cart_variation_params != 'undefined') { 105 if (jQuery(element).hasClass('variation-found')) { 106 window.alert(wc_add_to_cart_variation_params.i18n_unavailable_text); 107 } else { 108 window.alert(wc_add_to_cart_variation_params.i18n_make_a_selection_text); 109 } 110 } else { 111 console.log("Missing the wc_add_to_cart_variation_params"); 112 } 113 return false;
114 } 115 116 jQuery('body').addClass('processing'); 117 removeErrorMessages(); 118 jQuery(element).attr('disabled','disabled'); 119 jQuery(element).attr('inactive','inactive'); 120 jQuery(element).addClass('disabled'); 121 jQuery(element).addClass('loading'); 122 123 if (typeof wp !== 'undefined' && typeof wp.hooks !== 'undefined') { 124 wp.hooks.doAction('vippsBuySingleProduct', element, event); 125 } 126 127 var compatMode = jQuery(element).hasClass('compat-mode'); 128 if (typeof wp !== 'undefined' && typeof wp.hooks !== 'undefined') { 129 compatMode = wp.hooks.applyFilters('vippsBuySingleProductCompatMode', compatMode, element, event); 130 } 131 132 // In compatibility mode, we delegate to the existing buy now button instead of doing the logic 133 // ourselves. This allows more filters and actions in existing plugins to run. IOK 2019-02-26 134 if (compatMode) { 135 var form = jQuery(element).closest('form'); 136 var otherbutton = form.find('.single_add_to_cart_button').first(); 137 var compatAction = function () { 138 form.prepend('<input type=hidden id="vipps_compat_mode" name="vipps_compat_mode" value="1">'); 139 if (otherbutton.length>0) otherbutton.click(); 140 } 141 // If your theme or product is weird enough, you may need this 142 if (typeof wp !== 'undefined' && typeof wp.hooks !== 'undefined') { 143 compatAction = wp.hooks.applyFilters('vippsBuySingleProductCompatModeAction', compatAction, element, event); 144 } 145 compatAction(); 146 return false; 147 } 148 149 var data = {}; 150 if (element.data('product_id') || element.data('product_sku')) { 151 data = element.data(); 152 } else { 153 var form = element.closest('form.cart'); 154 if (!form) { 155 jQuery(element).removeClass('disabled'); 156 jQuery(element).removeClass('loading'); 157 jQuery(element).removeAttr('disabled'); 158 jQuery(element).removeAttr('inactive'); 159 jQuery('body').removeClass('processing'); 160 addErrorMessage('Cannot add product - unknown error'); 161 return false; 162 } 163 // Initialize with the entire content of the form if we have it. 164 var serialized = form.serializeArray(); 165 for (var i=0;i<serialized.length;i++) { 166 if (serialized[i]['name'] != 'add-to-cart') { 167 data[serialized[i]['name']] = serialized[i]['value']; 168 } 169 } 170 var prodid = jQuery(form).find('input[name="product_id"]'); 171 var varid = jQuery(form).find('input[name="variation_id"]'); 172 var quantity = jQuery(form).find('input[name="quantity"]'); 173 data['quantity'] = (quantity.length>0) ? quantity.val() : 1; 174 data['product_id'] = (prodid.length>0) ? prodid.val() : 0; 175 data['variation_id'] = (varid.length>0) ? varid.val() : 0; 176 // Earlier versions, no variation: 177 if (prodid.length == 0) { 178 prodid = jQuery(form).find('button[name="add-to-cart"]'); 179 if (prodid.length > 0) { 180 data['product_id'] = prodid.val(); 181 } else { 182 // Some weird themes are even more incompatible 183 prodid = jQuery(form).find('button[data-product_id]'); 184 data['product_id'] = prodid.length > 0 ? prodid.data('product_id') : 0; 185 } 186 } 187 } 188 // Finally, create a hook for even weirder themes. 189 data = wp.hooks.applyFilters('vippsBuySingleProductData', data, element, event); 190 data['action'] = 'vipps_buy_single_product'; 191 192 jQuery.ajax(VippsConfig['vippsajaxurl'], { 193 "method": "POST", 194 "data":data, 195 "cache":false, 196 "headers": {"Accept-Language": `${VippsConfig['vippslocale']}, *`}, 197 "dataType": "json", 198 "error": function (xhr, statustext, error) { 199 console.log("Error creating express checkout:" + statustext + " " + error); 200 addErrorMessage(error, element); 201 jQuery(element).prop('disabled',true); 202 jQuery(element).prop('inactive',true); 203 jQuery('body').removeClass('processing'); 204 }, 205 "success": function (result, statustext, xhr) { 206 if (result["ok"]) { 207 console.log("We created the order!"); 208 /* In case user presses the back button */ 209 setTimeout(function () { 210 jQuery(element).removeClass('disabled'); 211 jQuery(element).removeClass('loading'); 212 jQuery(element).removeAttr('disabled'); 213 jQuery(element).removeAttr('inactive'); 214 jQuery('body').removeClass('processing'); 215 } 216 , 1500); 217 window.location.assign(result["url"]); 218 } else { 219 console.log("Failure!"); 220 jQuery(element).removeClass('disabled'); 221 jQuery(element).removeClass('loading'); 222 jQuery(element).removeAttr('disabled'); 223 jQuery(element).removeAttr('inactive'); 224 addErrorMessage(result['msg'],element); 225 jQuery('body').removeClass('processing'); 226 } 227 }, 228 "timeout": 0 229 }); 230 231 } 232 233 234 235 // Remove old error messages 236 function removeErrorMessages () { 237 jQuery('.woocommerce-error.vipps-error').fadeOut(300, function () { jQuery(this).remove(); }); 238 jQuery(document).trigger('woo-vipps-remove-errors'); 239 if (typeof wp !== 'undefined' && typeof wp.hooks !== 'undefined') { 240 wp.hooks.doAction('vippsRemoveErrorMessages'); 241 } 242 } 243 244 // And add new ones 245 function addErrorMessage(msg,element) { 246 // Allow developers to customize error message by hiding vipps-default-error-message and hooking woo-vipps-error-message <messsage>,<element> 247 var msg = "<p><ul class='woocommerce-error vipps-error vipps-default-error-message vipps-buy-now-error'><li>
247"+msg+"!</li></ul></p>"; 248 if (typeof wp !== 'undefined' && typeof wp.hooks !== 'undefined') { 249 msg = wp.hooks.applyFilters('vippsErrorMessage',msg, element); 250 } 251 jQuery(document).trigger('woo-vipps-error-message',[msg, element]); 252 if (typeof wp !== 'undefined' && typeof wp.hooks !== 'undefined') { 253 wp.hooks.doAction('vippsAddErrorMessage', msg, element); 254 } 255 256 jQuery(msg).hide().insertAfter(element).fadeIn(300); 257 jQuery('.woocommerce-error.vipps-error').click(removeErrorMessages); 258 } 259 260 // Hooks for the button itself 261 function vippsInit() { 262 jQuery('.button.single-product.vipps-buy-now:not(.initialized)').click(buySingleProduct); 263 jQuery('.button.single-product.vipps-buy-now').addClass('initialized'); 264 if (typeof wp !== 'undefined' && typeof wp.hooks !== 'undefined') { 265 wp.hooks.doAction('vippsInit'); 266 } 267 } 268 269 vippsInit(); 270}); 271
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.