Created
September 6, 2018 16:42
-
-
Save ldco2016/b1b81e54b6faabed818331c2f293e840 to your computer and use it in GitHub Desktop.
show event on base class
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
//= require templates/modules/dvic_card_gallery | |
//= require templates/modals/exit_interstitial | |
//= require application/optimizely-metrics | |
//= require templates/modals/dvic_modal_card_gallery | |
//= require templates/modals/dvic_modal_card_gallery | |
/* jshint:false */ | |
(function(exports) { | |
"use strict"; | |
var Grill = exports.Grill, | |
Whiskers = exports.Whiskers, | |
Backbone = exports.Backbone, | |
Disney = exports.Disney, | |
Commerce = Disney.Commerce, | |
OptimizelyMetrics = exports.OptimizelyMetrics, | |
isNativeView = Disney.LocationHelpers.isNativeView, | |
Webkit = exports.window.webkit, | |
$ = exports.$, | |
_ = exports._; | |
var currentGallerySlide = 'card-sorcerer'; | |
var InstantCreditProduct = Backbone.Model.extend({ | |
// add methods | |
generate_url: function(args, userId) { | |
// now launch popup interstitial | |
var chaseConfig = fetchChaseConfig(); | |
var chase_return_uri = chaseConfig.chase_return_uri; | |
var chase_application_uri = chaseConfig.chase_application_uri; | |
// MHCOM-1759: When rendering a webview for the native mobile app, respect | |
// the environment sent by the app. Otherwise, we risk applying for real | |
// cards during testing. For safety, respect principle of mutal consent. | |
// The native app does not send the "environment" header when it wants | |
// to use Production, so the site's configuration has final say on the Chase URL. | |
if (Disney.nativeGuest && Disney.nativeGuest.environment) { | |
chase_application_uri = Disney.nativeGuest.environment; // will be overwritten in the native overrides | |
} | |
// build out the query string used to pop a new browser for Chase application | |
// cell will originally come from query string (default (63NH06) ) | |
var cell = Disney.LocationHelpers.getQueryParam("cell") || chaseConfig.cell; | |
// strip cell of any potential injected script | |
cell = cell && cell.replace(/<.*?>/g, '').replace(/[^\w\s]/gi, ''); | |
var params = { | |
CHASE_RETURN_URI: chase_return_uri, | |
CHASE_APPLICATION_URI: chase_application_uri, | |
CELL: cell, | |
CID: userId || '{insertCID}', | |
PROMO: args.promo, | |
CLICK: args.click, | |
SPID: args.spid, | |
CAT: args.cat, | |
CARDSTYLE: args.cardStyle, | |
RU: chase_return_uri | |
}; | |
// Apply parameter overrides for native views based on cofiguration. | |
params = applyNativeOverrides(chaseConfig, params); | |
// Process the URIs that were grouped into the params to make the overrides easier. | |
chase_application_uri = params.CHASE_APPLICATION_URI; | |
delete params.CHASE_APPLICATION_URI; | |
params.RU = params.CHASE_RETURN_URI; | |
delete params.CHASE_RETURN_URI; | |
// Encode the parameters and output the final URL. | |
return chase_application_uri + Disney.LocationHelpers.generateQueryParams(params); | |
} | |
}); | |
var CardGalleryView = Grill.ModuleView.extend({ | |
style_classes: ["full-width"], | |
required_template_sets: ["module_header"], | |
template: Whiskers.modules.dvic_card_gallery, | |
events:{ | |
"click .apply": function (e) { | |
e.preventDefault(); | |
var that = this, | |
chaseConfig = fetchChaseConfig(), | |
// if a user hasnt selected a card from the card selector at bottom of page, we'll default to Sorcerer Card | |
default_card = { | |
promo: chaseConfig.promo, | |
click: chaseConfig.click, | |
spid: this.spid || chaseConfig.spid, | |
cat: this.cat || chaseConfig.cat, | |
cardStyle: this.cardStyle || chaseConfig.cardStyle | |
}; | |
if (isNativeView()) { | |
handleNativeButtonClick(that, default_card); | |
} else { | |
handleWebButtonClick(that, default_card, e.target); | |
} | |
}, | |
"click .card-select": function (e) { | |
e.preventDefault(); | |
this.$clickedEl = $(e.currentTarget); | |
// cardstyle = spid|cat | |
var selectedCardStyle = this.$clickedEl.data("action"); | |
var results = selectedCardStyle.split("|"); | |
// remove any classes that may have it | |
$(".card-select").removeClass("selected"); | |
// set the border | |
this.$clickedEl.addClass("selected"); | |
$(exports).trigger('dvicCardSelected', { | |
"spid": results[0], | |
"cat": results[1], | |
"cardStyle": selectedCardStyle | |
}); | |
}, | |
'click .view-full-gallery': 'onClickLink' | |
}, | |
onClickLink: function(e) { | |
e.preventDefault(); | |
var modalConfig = { | |
template: Whiskers.modals.dvic_modal_card_gallery, | |
name: 'full-gallery', | |
ctx_additions: this.ctx_additions(), | |
linkEl: [e.target] | |
}; | |
if (this.modal === undefined) { | |
this.modal = new Grill.DvicFullGalleryModalView(modalConfig); | |
this.modal.show(); | |
} else { | |
// if the modal has already been created and closed, reopen it | |
this.modal.show(); | |
} | |
}, | |
initialize: function(){ | |
var that = this; | |
$(exports).on('dvicCardSelected', function(event, cardData) { | |
_.extend(that, cardData); | |
}); | |
Disney.guest.on('init', function() { | |
// Populate the template link hrefs. | |
setupTemplateLinks(that); | |
// Set the button text for the "Apply" button based on guest login state. | |
if(Disney.guest.current) { | |
setButtonCopy("Apply Now"); | |
Commerce.getUserProfile() | |
.done(function (response) { | |
_.extend(that, { | |
"userId": _.extend(response.profile.userId) | |
}); | |
}) | |
.fail(function () { | |
Disney.guest.login(); | |
setButtonCopy("Sign In & Apply"); | |
}); | |
} | |
}); | |
// For top apply button, we'll default to Sorcerer Mickey Card | |
Disney.guest.on('login', function() { | |
setButtonCopy("Apply Now"); | |
Commerce.getUserProfile() | |
.done(function (response) { | |
_.extend(that, { | |
"userId": _.extend(response.profile.userId) | |
}); | |
}); | |
}); | |
Disney.guest.on('logout', function() { | |
setButtonCopy("Sign In & Apply"); | |
}); | |
}, | |
render: function(){ | |
var ctx = _.extend(this.model, { | |
userId: this.userId, | |
termsAndConditionsHref: fetchTermsAndConditionsHref() | |
}); | |
this.$el.html(this.template.render(ctx, this.ctx_additions())); | |
} | |
}); | |
CardGalleryView.register("dvic_card_gallery", { }); | |
// We can only pull this configuration once the burger is fully instanciated, | |
// but we need a guard against misconfiguration. | |
var fetchChaseConfig = function() { | |
if (!Disney.chaseConfig) { | |
throw new Error("DVIC lacks configuration"); | |
} | |
return Disney.chaseConfig; | |
}; | |
// This pulls the link to the terms and conditions the guest needs to see. | |
var fetchTermsAndConditionsHref = function() { | |
var chaseConfig = fetchChaseConfig(), | |
href = chaseConfig.termsLink; | |
if (isNativeView() && chaseConfig.nativeDict && chaseConfig.nativeDict.termsLink) { | |
href = chaseConfig.nativeDict.termsLink; | |
} | |
return href; | |
}; | |
// Return mobile override values by mapping from the original desktop value, | |
// but only apply if mobile values exist. Curried on the candidate dictionary. | |
var safeAssign = function(dict) { | |
return function(original, name) { | |
if (dict && dict[name]) { | |
if (typeof dict[name] === "object") { | |
// objects are mappings for individual parameters | |
return dict[name][original] || original; | |
} else { | |
// Simple string to return | |
return dict[name]; | |
} | |
} else { | |
return original; | |
} | |
}; | |
}; | |
// MHCOM-1759: This if-chain allows for the optional override of DVIC configurations | |
// to support native needs. It allows the native team the flexibility | |
// to update values with only configuration changes. For native | |
// views, we look up the native override dictionary. We then apply | |
// overrides directly or use hashes to map desktop parameter values onto native ones. | |
var applyOverrides = function(params, assign) { | |
var keys = ["chase_return_uri", "chase_application_uri", "cell", "cid", "promo", "click", "spid", "cat", "cardStyle"]; | |
_.each(keys, function(key){ | |
params[key.toUpperCase()] = assign(params[key.toUpperCase()], key); | |
}); | |
return params; | |
}; | |
var applyNativeOverrides = function(chaseConfig, original) { | |
if (isNativeView() && chaseConfig && chaseConfig.nativeDict) { | |
return applyOverrides(original, safeAssign(chaseConfig.nativeDict)); | |
} | |
return original; | |
}; | |
// MHCOM-1759: For the native application, a webview is used to render the app | |
// page. This WebKit messaging is used to signal to that app. Otherwise, | |
// in non-WebKit viewers, this is a No-Op. | |
var webkitMessage = function(id, url) { | |
if (Webkit) { | |
Webkit.messageHandlers.buttonClicked.postMessage({ ButtonId: id, Url: url }); | |
} | |
}; | |
// MHCOM-1759: In the native view, we need to pass a given link's href to the | |
// native app so that the app can hand the navigation off to a real browser. | |
var setupTemplateLinks = function(that){ | |
var href = fetchTermsAndConditionsHref(); | |
if (isNativeView()) { | |
that.$(".termsAndConditions").on("click", function(e){ | |
e.preventDefault(); | |
webkitMessage("terms", href); | |
}); | |
that.$(".external-link").each(function(){ | |
var href = $(this).attr("href"); | |
$(this).on("click", function(e){ | |
e.preventDefault(); | |
webkitMessage("externalLink", href); | |
}); | |
}); | |
} | |
}; | |
var trackStartApplication = function() { | |
OptimizelyMetrics.pushEvent('instantcredit_startApplication'); | |
}; | |
// MHCOM-1759: Either send the guest to the native login, or use the native | |
// access token value in the call to the v4 API so we can generate the Chase URL. | |
var handleNativeButtonClick = function(that, default_card) { | |
if (!Disney.nativeGuest) { | |
var chaseUrl = new InstantCreditProduct().generate_url(default_card, false); | |
return webkitMessage('login', chaseUrl); | |
} else { | |
Commerce.getUserProfile(Disney.nativeGuest) | |
.done(function (response) { | |
_.extend(that, { | |
"userId": _.extend(response.profile.userId) | |
}); | |
var popup_url = new InstantCreditProduct().generate_url(default_card, that.userId); | |
return webkitMessage("applyNow", popup_url); | |
}); | |
} | |
}; | |
// Exclusively use the site's OneID interface to generate the Chase URL. | |
var handleWebButtonClick = function(that, default_card, linkEl) { | |
var instantcreditproduct = new InstantCreditProduct(), | |
popup_url = ""; | |
// In some cases userId will return undefined even if logged in, mainly with | |
// new accounts. Need to check its presence here before proceeding. | |
if (false && Disney.guest.current && that.userId) { | |
popup_url = instantcreditproduct.generate_url(default_card, that.userId); | |
// The interstitial modal alerts the guest that they are leaving Store. | |
Disney.Utilities.launchExitInterstitialPage(that, Grill, Whiskers, popup_url, linkEl, trackStartApplication); | |
} else { | |
// Log the guest in, and then build the Chase URL. | |
Disney.guest.login().done(function () { | |
that.$(".phase-1").fadeOut(300, function() { | |
that.$(".phase-2").fadeIn(300); | |
that.$(".phase-2 > a").focus(); | |
}); | |
}) | |
.then(function() { | |
Commerce.getUserProfile() | |
.done(function (response) { | |
_.extend(that, { | |
"userId": _.extend(response.profile.userId) | |
}); | |
popup_url = instantcreditproduct.generate_url(default_card, that.userId); | |
Disney.Utilities.launchExitInterstitialPage(that, Grill, Whiskers, popup_url, linkEl, trackStartApplication); | |
}); | |
}); | |
} | |
}; | |
// Based on the guest login state, we need to adjust the button copy. This helper makes that easier. | |
var setButtonCopy = function(str) { | |
$("#apply1").html(str); | |
$("#apply2").html(str); | |
$('.linktext').html(str); | |
}; | |
// MHCOM-1759: The native mobile app needs a way to communicate OneID login | |
// information to the page. This function is invoked using webkit.evaluateJavascript | |
// within the app, passing in the OneID temporary accessToken. Afterwards, we need the | |
// page to appear logged-in. Even though the site's guest context cannot have the full context | |
// from the the app, it is enough to get the userID from the Commerce API. | |
Grill.nativeMobileLogin = function(token, env) { | |
// Validate incoming environment to guard against injection attacks. | |
if (env !== "test1" && env !== "test2") { | |
env = false; | |
} | |
// Validate the incoming token to guard against injection attacks. | |
if (/^[0-9a-f]{32}$/.test(token.toLowerCase())) { | |
Disney.nativeGuest = { | |
token: {access_token: token}, | |
environment: env | |
}; | |
setButtonCopy("Apply Now"); | |
} else { | |
throw new Error("Unable to validate injected OneID access token."); | |
} | |
}; | |
// Create Modal View | |
Grill.DvicFullGalleryModalView = Grill.ModalView.extend({ | |
render: function() { | |
exports.console.log('the modalview is now being rendered'); | |
var modal_ctx = { | |
cta_button: this.options.cta_button | |
}; | |
return this.options.template.render(modal_ctx); | |
}, | |
events: { | |
'click .sp-thumbnail': 'onClickThumbnail', | |
'click .sp-forward': 'onClickForwardChevron', | |
'click .sp-backward': 'onClickBackwardChevron' | |
}, | |
onClickThumbnail: function(e) { | |
e.preventDefault(); | |
exports.console.log('onClickThumbnail working!'); | |
this.$clickedEl = $(e.currentTarget); | |
// Tells us what card was clicked. | |
var clickedCard = this.$clickedEl.data('action').trim(); | |
currentGallerySlide = clickedCard; | |
// Hide all , then show what was clicked. | |
$('.sp-slides .sp-slide').hide(); | |
$('.sp-slides .sp-slide.' + clickedCard).show(); | |
this.updateThumbnails(); | |
}, | |
onClickForwardChevron: function(e) { | |
e.preventDefault(); | |
galleryButtonClick(currentGallerySlide, 'forward'); | |
this.updateThumbnails(); | |
// rightChevronClick(); | |
}, | |
onClickBackwardChevron: function(e) { | |
e.preventDefault(); | |
galleryButtonClick(currentGallerySlide, 'backward'); | |
this.updateThumbnails(); | |
// leftChevronClick(); | |
}, | |
updateThumbnails: function() { | |
var $slides = this.$('.sp-slides .sp-slide'), | |
slidesLength = $slides.length, | |
index = $slides.index($slides.siblings('.' + currentGallerySlide)), | |
thumbnailWidth = this.$('.sp-thumbnail').outerWidth(true), | |
offsetModifier = (slidesLength % 2 === 0) ? 0.5 : 0, // Modify if number of cards is even | |
offset = -1 * (index - (slidesLength / 2) + offsetModifier), // Offset from center | |
translate = offset * thumbnailWidth; | |
this.$('.thumbnail-container').css('transform', 'translateX(' + translate + 'px)'); | |
} | |
}); | |
//========================== | |
// Helpers | |
//========================== | |
var galleryButtonClick = function(cardName, direction) { | |
// this array must match the card order in the template | |
var cardsArray = [ | |
'card-sorcerer', | |
'card-th', | |
'card-pals', | |
'card-vader', | |
'card-pixie', | |
'card-tinker', | |
'card-frozen', | |
'card-bb8', | |
'card-yoda', | |
'card-spotlight' | |
]; | |
var index = cardsArray.indexOf(cardName); | |
$('.sp-slides .sp-slide').hide(); | |
// get the card to show | |
if (direction === 'forward' && index === cardsArray.length - 1) { | |
currentGallerySlide = cardsArray[0]; | |
} else if (direction === 'forward') { | |
currentGallerySlide = cardsArray[index + 1]; | |
} else if (direction === 'backward' && index === 0) { | |
currentGallerySlide = cardsArray[cardsArray.length - 1]; | |
} else if (direction === 'backward') { | |
currentGallerySlide = cardsArray[index - 1]; | |
} | |
$('.sp-slides .sp-slide.' + currentGallerySlide).show(); | |
}; | |
})(this); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment