PageSourceSearch

https://www.gerritys.com/wp-content/plugins/shoptocook-recipes/js/recipes.js?ver=1776207150

js gerritys.com collected 2026-10-07 23:23:08 UTC 21,599 bytes, 440 lines download raw bytes

1var S = {
2    initialize: function (type, search) {
3        S.recipeManager.initialize(type, search);
4        S.layoutManager.initialize(S.recipeManager.onPageScroll);
5        S.searchManager.initialize();
6        S.shoppingManager.initialize();
7    },
8    imageManager: {
9        onImageLoad: function (a) {
10            a.className += ' loaded';
11        }
12    },
13    socialManager: {
14        analytics: {
15            track: function (id) {
16                if (typeof gtag === 'function') {
17                    gtag('event', 'page_view', { 'page_location': stcajax.urlbase + '/recipes/recipe-details/' + id + '/' });
18                    gtag('event', 'view_recipe', { 'value': 'Recipe ' + id });
19                }
20            }
21        },
22        facebook: {
23            initialize: function () {
24                var js, fjs = document.getElementsByTagName('script')[0];
25                if (document.getElementById('facebook-jssdk'))
26                    return;
27                js = document.createElement('script');
28                js.id = 'facebook-jssdk';
29                js.src = "//connect.facebook.net/en_US/all.js#xfbml=1";
30                fjs.parentNode.insertBefore(js, fjs);
31            },
32            link: function () {
33                try {
34                    FB.XFBML.parse();
35                } catch (err) {
36                    //ignore
37                }
38            }
39        },
40        pinterest: {
41            initialize: function () {
42                var f = document.getElementsByTagName('SCRIPT')[0];
43                var p = document.createElement('SCRIPT');
44                p.type = 'text/javascript';
45                p.async = true;
46                p.src = '//assets.pinterest.com/js/pinit.js';
47                f.parentNode.insertBefore(p, f);
48            },
49            get: function () {
50                for (var i in window) {
51                    if (i.indexOf('PIN_') == 0 && typeof window[i] == 'object') {
52                        return window[i];
53                    }
54                }
55            },
56            link: function () {
57                S.socialManager.pinterest.get().f.seek.buttonPin(jQuery('.pin')[0]);
58            }
59        }
60    },
61    layoutManager: {
62        $container: null,
63        $document: null,
64        $window: null,
65        $icon: null,
66        $error: null,
67        factory: null,
68        itemWidth: 200,
69        count: 0,
70        increment: 12,
71        maxCount: -1,
72        scrollOffset: 100, /* DEPRECATED */
73        onScrollAjax: false,
74        wookmark: null,
75        initialize: function (onPageScroll) {
76            S.layoutManager.factory = onPageScroll;
77            S.layoutManager.$window = jQuery(window);
78            S.layoutManager.$document = jQuery(document);
79            S.layoutManager.$container = jQuery('#stc-main-content');
80            S.layoutManager.$icon = jQuery('.grid-icon');
81            S.layoutManager.$error = jQuery('.grid-error');
82            S.layoutManager.wookmark = new Wookmark('#stc-main-content', {
83                offset: 15 // Optional, the distance between grid items
84            });
85            jQuery(window).bind('scroll.wookmark', S.layoutManager.onPageScroll);
86        },
87        generateHTML: function (json) {
88            var html = '';
89            json['recipes'].forEach(function (recipe) {
90                html += '<div class="stc-rcp-item" style="width:' + S.layoutManager.itemWidth + 'px;">' +
91                    '<a class="stc-cat-link" href="' + stcajax.urlbase + '/recipes/recipe-details/' +
92                    recipe['recipe_id'] + '" onClick="return S.recipeManager.onDetailClick(\'' + recipe['recipe_id'] + '\', true);">' +
93                    '<div class="item-wrapper">' +
94                    '<div class="item-overlay">' +
95                    '<div class="item-image">' +
96                    '<div class="image-wrapper no-scroll" style="width:' + S.layoutManager.itemWidth + 'px; height:' + S.layoutManager.itemWidth + 'px;">' +
97                    '<div class="dim-wrapper">' +
98                    '<div class="dim-overlay"></div></div>' +
99                    '<img class="item-image fade" onload="S.imageManager.onImageLoad(this)" src="https://images.shoptocook.com' + recipe['image_full'] + '" alt="' + recipe['recipe_name'] + '">' +
100                    '</div></div>' +
101                    '<div class="item-summary">';
102                html += '<span>' + recipe['recipe_name'] + '</span>' +
103                    '</div>';
104                if (recipe['image_credit'] !== "") {
105                    html += '<div class="credit-container">' +
106                        '<span>' +
107                        recipe['image_credit'] + '</span></div>';
108                }
109                html += '</div></div></a></div>';
110            });
111            return html;
112        },
113        onPageScroll: function () {
114            if (typeof S.layoutManager.factory !== "function") {
115                return;
116            }
117
118            var viewportHeight = window.innerHeight ? window.innerHeight : S.layoutManager.$window.height();
119            var recipeBottom = jQuery('#recipe_container_outer .header-line-sub').get(0).getBoundingClientRect().top;
120            //look at removal of scroll offsets and put scroll offset back in here
121            //S.layoutManager.scrollOffset
122            if (recipeBottom + 100 < viewportHeight && !S.layoutManager.onScrollAjax && S.layoutManager.search !== null && (S.layoutManager.maxCount === -1 || S.layoutManager.count < S.layoutManager.maxCount)) {
123                S.layoutManager.$icon.addClass("grid-spinner");
124                S.layoutManager.onScrollAjax = true;
125                S.layoutManager.factory(
126                    function (data) {
127                        if (data === null || data['error_message']) {
128                            S.layoutManager.$icon.addClass("grid-spinner");
129                            S.layoutManager.$error.html(data !== null ? data['error_message'] : 'An error occured.');
130                            S.layoutManager.$error.show();
131                            return;
132                        }
133
134                        S.layoutManager.setup(data, 0);
135                        S.layoutManager.onScrollAjax = false;
136                        S.layoutManager.$icon.removeClass("grid-spinner");
137                    });
138            }
139        },
140        setup: function (json, fadeTimeout) {
141            S.layoutManager.count += S.layoutManager.increment;
142            S.layoutManager.maxCount = json['total_recipes'];
143            var $items = jQuery(S.layoutManager.generateHTML(json)).css('opacity', 0);
144            S.layoutManager.$container.append($items);
145            S.layoutManager.wookmark.initItems();
146            if (fadeTimeout > 0) {
147                S.layoutManager.wookmark.layout(true, function () {
148                    setTimeout(function () {
149                        $items.fadeTo(300, 1);
150                    }, fadeTimeout);
151                });
152            } else {
153                S.layoutManager.wookmark.layout(true, function () {
154                    $items.fadeTo(300, 1);
155                });
156            }
157        }
158    },
159    recipeManager: {
160        $overlay: null,
161        type: null,
162        search: null,
163        history: null,
164        initialize: function (type, search) {
165            S.recipeManager.type = type;
166            S.recipeManager.search = search;
167            S.recipeManager.$overlay = jQuery('<div id="append-container"></div>');
168            jQuery('body').append(S.recipeManager.$overlay);
169        },
170        bindBackButton: function () {
171            S.recipeManager.history = window.History;
172            S.recipeManager.history.Adapter.bind(window, 'statechange', function () {
173                var states = S.recipeManager.history.getState()
174                if (jQuery.trim(S.recipeManager.$overlay.html()) === '') {
175                    S.recipeManager.onDetailClick(states.data["id"], false);
176                } else if (jQuery.isEmptyObject(states.data)) {
177                    S.recipeManager.closePopup();
178                }
179            });
180        },
181        bindCloseButton: function (f) {
182            jQuery('.RecFooterClose, .overlay').click(f);
183        },
184        closePopup: function () {
185            S.recipeManager.$overlay.empty();
186            jQuery('body').removeClass('no-scroll');
187            jQuery('html').removeClass('no-scroll');
188        },
189        onDetailClick: function (id, history) {
190            S.recipeManager.$overlay.append(
191                '<div class="overlay">' +
192                '<button class="RecCloseButton borderless" aria-label="Close"><em class="stc-icon-xxsmall" style="font-size:0px;line-height:0px;">Close</em></button>' +
193                '<div id="overlay-content-wrapper" style="margin-top: 28px; margin-bottom: 14px;">' +
194                '</div>' +
195                '</div>');
196            jQuery('body').addClass('no-scroll');
197            jQuery('html').addClass('no-scroll');
198            jQuery('.RecCloseButton').addClass('transformVisible');
199            S.recipeManager.bindCloseButton(S.recipeManager.onPopupCloseClick);
200            if (S.recipeManager.history !== null && history) {
201                S.recipeManager.history.pushState({ url: document.location.href, id: id }, document.title, window.location.protocol + '//' + window.location.hostname + stcajax.urlbase + '/recipes/recipe-details/' + id + '/');
202            }
203            var data = {
204                'action': 'stc_get_recipe',
205                'id': id
206            };
207            jQuery.post(stcajax.ajaxurl, data, function (response) {
208                if (response === null || response['error_message']) {
209                    return;
210                }
211
212                S.recipeManager.parseJson(response);
213            }, "json");
214            return false;
215        },
216        onDetailCloseClick: function (e) {
217            if (jQuery(e.target).parents(".overlay-content").length !== 1) {
218                window.location.href = stcajax.urlbase + "/recipes";
219            }
220        },
221        onPopupCloseClick: function (e) {
222            if (jQuery(e.target).parents(".overlay-content").length !== 1) {
223                S.recipeManager.history.back();
224            }
225        },
226        parseJson: function (data) {
227            var $wrapper = jQuery('#overlay-content-wrapper');
228            var url = encodeURIComponent('http://' + window.location.hostname + '/recipe-details/' + data['id'] + '/');
229            var html = '';
230            html += '<div class="overlay-content"><div class="RecActionBar">';
231            if (stcajax.urlbase == '') {
232                html += '<div class="floatLeft">'
233                    + '<a class="RecActionButton pin first" data-pin-do="buttonPin" data-pin-count="beside" data-pin-custom="true" '
234                    + 'href="https://www.pinterest.com/pin/create/button/?url=' + url
235                    + '&media=' + encodeURIComponent('https://images.shoptocook.com' + data['image'])
236                    + '&description=' + encodeURIComponent(data['name']) + '">'
237                    + '<img src="/wp-content/plugins/shoptocook-recipes/images/blank.png" height="24" width="48" alt="pinterest"/></a>'
238                    + '<div class="fb-like" data-href="' + url + '" data-layout="button" data-action="like" data-show-faces="true" data-share="true"></div>'
239                    + '</div>';
240            }
241            html += '<div class="floatRight">';
242            if (stcajax.urlbase == '') {
243                html += '<a class="RecActionButton email first" href="mailto:?subject=Recipe: ' + data['name']
244                    + '&amp;body=' + url + '">'
245                    + '<em class="stc-icon-xxsmall"></em> <span>Send</span></a>'
246            }
247            html += '<a class="RecActionButton print" href="' + stcajax.urlbase + '/print-recipe/?recipeid=' 
247+ data['id'] + '">'
248                + '<em class="stc-icon-xxsmall"></em> <span>Print</span></a>'
249                + '</div></div><div>'
250                + '<img src="https://images.shoptocook.com' + data['image'] + '" alt="' + data['name'].replace(/\"/g, "") + ' banner" />'
251                + '</div>';
252            html += '<div class="sub-content"><h2 class="overlay-header">'
253                + data['name'] + '</h2>';
254            if (data['image_credit'] !== "") {
255                html += '<span class="stc-recipe-credit">' + data['image_credit'] + '</span>';
256            }
257            html += '<span class="sub-header">';
258            var subhtml = '';
259            for (i = 0; i < data['header'].length; i++) {
260                if (data['header'][i]['display_value'] === 'n/a') {
261                    continue;
262                }
263                if (subhtml !== '') {
264                    subhtml += ' &#8226; ';
265                }
266                if (data['header'][i]['display_name'] === 'Serve With') {
267                    subhtml += data['header'][i]['display_value'];
268                } else {
269                    subhtml += data['header'][i]['display_value'] + ' ' + data['header'][i]['display_name'];
270                }
271            }
272            html += subhtml;
273            if (data['vendor_logo'] != null && data['vendor_logo'] !== "") {
274                html += '<div style="margin-top: 20px;">
274<img src="https://images.shoptocook.com/' + data['vendor_logo'] + '" alt="Sponsor" /></div>';
275            }
276            html += '</span></div><div class="sub-content"><div class="ingredient-container">'
277                + '<h3>Ingredients</h3><table>';
278            for (i = 0; i < data['ingredients'].length; i++) {
279                var checkid = 'ingredient-' + data['id'] + '-' + i;
280                html += '<tr'
281                    + ((i < data['ingredients'].length - 1) ? ' class="underline"' : "")
282                    + '><td>';
283                if (data['ingredients'][i]['can_add'] === "Y") {
284                    html += '<input type="checkbox" id="' + checkid
285                        + '" class="ingredient-checkbox" data-name="'
286                        + data['ingredients'][i]['name'] + '" data-id="'
287                        + data['id'] + '" /><label for="' + checkid + '"><span style="display:none;">' + data['ingredients'][i]['name'].replace(/\"/g, "")
288                        + '</span></label>';
289                }
290                html += '<span class="ingredient-name">'
291                    + (data['ingredients'][i]['name'] === "\n" ? '<br/>' : data['ingredients'][i]['name'])
292                    + '</span></td></tr>';
293            }
294            html += '</table></div></div><div class="sub-content"><h3>Directions:</h3>';
295            data['instructions'].forEach(function (instruction) {
296                html += '<p>' + instruction['line'] + '</p>';
297            });
298            html += '</div>';
299            if (typeof data['nutrition'] !== 'undefined' && data['nutrition'].length > 0) {
300                html += '<div class="sub-content"><h3>Nutrition:</h3>';
301                data['nutrition'].forEach(function (nutrition) {
302                    html += '<span>' + nutrition['display_name'] + ': ' + nutrition['display_value'] + ' </span>';
303                });
304                html += '</div>';
305            }
306
307            if (typeof data['wine_pairings'] !== 'undefined' && data['wine_pairings'].length > 0) {
308                html += '<div class="sub-content"><h3>Wine Pairings:</h3><span>'
309                    + data['wine_pairings'].join(', ')
310                    + '</span></div>';
311            }
312            html += '</div>'
313                + '<div class="stc-footer-close"><a class="RecFooterClose stc-button"><img src="/wp-content/plugins/shoptocook-recipes/images/close-button.png" alt="close"></a>'
314                + '</div>';
315            $wrapper.append(html);
316            S.shoppingManager.bindInputs();
317            S.socialManager.analytics.track(data['id']);
318            if (stcajax.urlbase == '') {
319                S.socialManager.pinterest.link();
320                S.socialManager.facebook.link();
321            }
322        },
323        onPageScroll: function (callback) {
324            var data = {
325                'action': 'stc_get_recipes',
326                'q': S.recipeManager.search,
327                'type': S.recipeManager.type,
328                'count': S.layoutManager.count,
329                'inc': S.layoutManager.increment
330            };
331            jQuery.post(stcajax.ajaxurl, data, function (response) {
332                if (typeof callback === "function") {
333                    callback(response);
334                }
335            }, "json");
336        }
337    },
338    shoppingManager: {
339        $shoppingList: null,
340        $badge: null,
341        isAnimating: false,
342        initialize: function () {
343            S.shoppingManager.$shoppingList = jQuery('<div class="stc-cart-overlay"></div>');
344            jQuery('body').append(S.shoppingManager.$shoppingList);
345            addLoadEvent(S.shoppingManager.show);
346        },
347        add: function (recpieId, ingredientName) {
348            if (typeof gtag === 'function') {
349                gtag('event', 'add_to_shoppinglist', { 'category': 'Recipes', 'value': ingredientName });
350            }
351            shoppinglist_controller.addToList(
352                {
353                    recipeID: recpieId,
354                    ingredient: ingredientName,
355                    department: 'Recipe Ingredients',
356                    dealDetails: null,
357                    details: null,
358                    terminationDate: null,
359                    storeID: null
360                },
361                function (result) {
362                    S.shoppingManager.animateBadge(result['items'].length);
363                });
364        },
365        animateBadge: function (count) {
366            if (S.shoppingManager.isAnimating) {
367                S.shoppingManager.$badge.children(":first").html(count);
368                return;
369            }
370
371            S.shoppingManager.$badge.css('visibility', 'visible');
372            S.shoppingManager.isAnimating = true;
373            S.shoppingManager.$shoppingList.toggle({
374                effect: "scale", complete: function () {
375                    S.shoppingManager.$badge.children(":first").html(count);
376                    S.shoppingManager.$shoppingList.toggle({
377                        effect: "scale", complete: function () {
378                            S.shoppingManager.isAnimating = false;
379                        }
380                    });
381                }
382            });
383        },
384        addClick: function (e) {
385            var $input = jQuery('#' + jQuery(e.target).attr('for'));
386            if ($input.prop('checked')) {
387                e.preventDefault();
388            } else {
389                S.shoppingManager.add($input.data('id'), $input.data('name'));
390            }
391        },
392        bindInputs: function () {
393            jQuery('.ingredient-checkbox + label').click(S.shoppingManager.addClick);
394        },
395        overlayClick: function (e) {
396            window.location.href = stcajax.urlbase + "/my-shopping-list";
397        },
398        show: function () {
399            S.shoppingManager.$shoppingList.append(
400                '<div class="img-wrapper"  title="Shopping List">' +
401                '<button class="stc-button stc-button-shop borderless" ' +
402                'type="button"><em><span style="display: none;">Shopping Cart<span></em></button><div class="stc-button ' +
403                'stc-badge-shop"><span class="stc-button-text stc-badge-text">' +
404                '</span></div></div>');
405            S.shoppingManager.$badge = jQuery('.stc-badge-shop');
406            jQuery('.stc-button-shop, .stc-badge-shop').click(S.shoppingManager.overlayClick);
407            shoppinglist_controller.initializeList(
408                function (result) {
409                    if (result['items'].length !== 0) {
410                        S.shoppingManager.$badge.children(":first").html(result['items'].length);
411                        S.shoppingManager.$badge.css('visibility', 'visible');
412                    }
413                });
414        }
415    },
416    searchManager: {
417        $input: null,
418        $main: null,
419        $window: null,
420        offset: 0,
421        initialize: function () {
422            S.searchManager.$input = jQuery('#stc-search-header');
423            S.searchManager.$window = jQuery(window);
424            S.layoutManager.$document = jQuery(document);
425            S.searchManager.$main = jQuery('.scroll-top-marker');
426            jQuery(document).ready(
427                function () {
428                    jQuery(window).scroll(function () {
429                        if (!S.searchManager.$input.hasClass("stc-search-float")
430                            && S.searchManager.$main.position().top - S.searchManager.offset < S.searchManager.$window.scrollTop()) {
431                            jQuery("#stc-search-header").addClass("stc-search-float");
432                        } else if (S.searchManager.$input.hasClass("stc-search-float")
433                            && S.searchManager.$main.position().top - S.searchManager.offset > S.searchManager.$window.scrollTop()) {
434                            jQuery("#stc-search-header").removeClass("stc-search-float");
435                        }
436                    });
437                });
438        }
439    }
440};

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.