diff --git a/third_party/subscriptions-project/config.js b/third_party/subscriptions-project/config.js
index 93f919c3e03a..b774617c268d 100644
--- a/third_party/subscriptions-project/config.js
+++ b/third_party/subscriptions-project/config.js
@@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-/** Version: 0.1.22.161 */
+/** Version: 0.1.22.163 */
/**
* Copyright 2018 The Subscribe with Google Authors. All Rights Reserved.
*
diff --git a/third_party/subscriptions-project/swg-button.css b/third_party/subscriptions-project/swg-button.css
index fc79c918048b..a064fb5744f8 100644
--- a/third_party/subscriptions-project/swg-button.css
+++ b/third_party/subscriptions-project/swg-button.css
@@ -288,17 +288,36 @@
min-height: 44px;
display: inline-flex;
align-items: center;
- box-shadow: 0px 1px 2px rgba(60, 64, 67, 0.3), 0px 1px 3px 1px rgba(60, 64, 67, 0.15);
box-sizing: border-box;
font-family: 'Google Sans', 'Roboto-Regular', sans-serif, arial;
font-weight: 500;
font-size: 14px;
letter-spacing: .001em;
+ cursor: pointer;
}
.swg-button-v2-light {
color: #1A73E8;
background-color: #fff;
+ border: 1px solid #DADCE0;
+}
+
+.swg-button-v2-light:hover {
+ box-shadow: 0px 1px 2px rgba(60, 64, 67, 0.3), 0px 1px 3px 1px rgba(60, 64, 67, 0.15);
+ background: linear-gradient(0deg, rgba(26, 115, 232, 0.04), rgba(26, 115, 232, 0.04)), #FFFFFF;
+ border: none;
+}
+
+.swg-button-v2-light:focus {
+ box-shadow: 0px 1px 2px rgba(60, 64, 67, 0.3), 0px 2px 6px 2px rgba(60, 64, 67, 0.15);
+ background: linear-gradient(0deg, rgba(26, 115, 232, 0.08), rgba(26, 115, 232, 0.08)), #FFFFFF;
+ border: none;
+}
+
+.swg-button-v2-light:active {
+ background-color: #fff;
+ box-shadow: 0px 6px 10px 4px rgba(60, 64, 67, 0.15), 0px 2px 3px rgba(60, 64, 67, 0.3);
+ border: none;
}
.swg-button-v2-dark {
@@ -306,6 +325,14 @@
background-color: #3C4043;
}
+.swg-button-v2-dark:hover, .swg-button-v2-dark:active {
+ box-shadow: 0px 2px 6px 2px rgba(0, 0, 0, 0.15), 0px 1px 2px rgba(0, 0, 0, 0.3);
+}
+
+.swg-button-v2-dark:focus {
+ box-shadow: 0px 6px 10px 4px rgba(0, 0, 0, 0.15), 0px 2px 3px rgba(0, 0, 0, 0.3);
+}
+
.swg-button-v2-icon-light,
.swg-button-v2-icon-dark {
width: 18px;
diff --git a/third_party/subscriptions-project/swg-gaa.js b/third_party/subscriptions-project/swg-gaa.js
index 43a55592cb9b..5e876571cdb7 100644
--- a/third_party/subscriptions-project/swg-gaa.js
+++ b/third_party/subscriptions-project/swg-gaa.js
@@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-/** Version: 0.1.22.161 */
+/** Version: 0.1.22.163 */
/**
* Copyright 2018 The Subscribe with Google Authors. All Rights Reserved.
*
@@ -35,13 +35,17 @@
const I18N_STRINGS = {
'SHOWCASE_REGWALL_TITLE': {
+ 'cs': 'Získejte s Googlem víc',
'de': 'Immer gut informiert mit Google',
'en': 'Get more with Google',
'es-ar': 'Disfruta más artículos con Google',
'fr': 'Plus de contenus avec Google',
+ 'it': 'Con Google puoi avere di più',
'pt-br': 'Veja mais com o Google',
},
'SHOWCASE_REGWALL_DESCRIPTION': {
+ 'cs':
+ 'Tento obsah je obvykle zpoplatněn, ale pokud se do publikace AP News{publication} zaregistrujete pomocí účtu Google, získáte od Googlu přístup zdarma.',
'de':
'Dieser Inhalt ist normalerweise kostenpflichtig. Google gewährt dir jedoch kostenlos Zugriff auf diesen Artikel und andere Inhalte, wenn du dich mit deinem Google-Konto bei AP News{publication} registrierst.',
'en':
@@ -50,21 +54,27 @@ const I18N_STRINGS = {
'Normalmente, es necesario pagar para ver este contenido, pero Google te ofrece acceso gratuito a este y otros artículos si te registras en AP News{publication} con tu Cuenta de Google.',
'fr':
'Ce contenu est généralement payant, mais vous pouvez lire cet article et d\'autres contenus gratuitement grâce à Google en vous inscrivant sur AP News{publication} avec votre compte Google.',
+ 'it':
+ 'Generalmente questi contenuti sono a pagamento, ma Google ti offre accesso gratuito a questo articolo e ad altri articoli se ti registri a AP News{publication} usando il tuo Account Google.',
'pt-br':
'Normalmente, é preciso pagar por este conteúdo. Porém, basta você se registrar na publicação AP News{publication} usando sua Conta do Google para ter acesso gratuito a esta matéria e muito mais.',
},
'SHOWCASE_REGWALL_PUBLISHER_SIGN_IN_BUTTON': {
+ 'cs': 'Už máte účet?',
'de': 'Du hast bereits ein Konto?',
'en': 'Already have an account?',
'es-ar': '¿Ya tienes una cuenta?',
'fr': 'Vous avez déjà un compte ?',
+ 'it': 'Hai già un account?',
'pt-br': 'Já tem uma conta?',
},
'SHOWCASE_REGWALL_GOOGLE_SIGN_IN_BUTTON': {
+ 'cs': 'Přihlásit se přes Google',
'de': 'Über Google anmelden',
'en': 'Sign in with Google',
'es-ar': 'Acceder con Google',
'fr': 'Se connecter avec Google',
+ 'it': 'Accedi con Google',
'pt-br': 'Fazer login com o Google',
},
};
diff --git a/third_party/subscriptions-project/swg.js b/third_party/subscriptions-project/swg.js
index 8673b90e6179..31399c54f2e1 100644
--- a/third_party/subscriptions-project/swg.js
+++ b/third_party/subscriptions-project/swg.js
@@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-/** Version: 0.1.22.161 */
+/** Version: 0.1.22.163 */
/**
* Copyright 2018 The Subscribe with Google Authors. All Rights Reserved.
*
@@ -57,6 +57,7 @@ const AnalyticsEvent = {
IMPRESSION_SHOWCASE_REGWALL: 23,
IMPRESSION_SWG_SUBSCRIPTION_MINI_PROMPT: 24,
IMPRESSION_SWG_CONTRIBUTION_MINI_PROMPT: 25,
+ IMPRESSION_CONTRIBUTION_OFFERS: 26,
ACTION_SUBSCRIBE: 1000,
ACTION_PAYMENT_COMPLETE: 1001,
ACTION_ACCOUNT_CREATED: 1002,
@@ -91,6 +92,7 @@ const AnalyticsEvent = {
ACTION_SWG_CONTRIBUTION_MINI_PROMPT_CLICK: 1031,
ACTION_SWG_SUBSCRIPTION_MINI_PROMPT_CLOSE: 1032,
ACTION_SWG_CONTRIBUTION_MINI_PROMPT_CLOSE: 1033,
+ ACTION_CONTRIBUTION_OFFER_SELECTED: 1034,
EVENT_PAYMENT_FAILED: 2000,
EVENT_CUSTOM: 3000,
EVENT_CONFIRM_TX_ID: 3001,
@@ -4471,9 +4473,10 @@ function adsUrl(url) {
/**
* @param {string} url Relative URL, e.g. "/offersiframe".
* @param {string=} prefix
+ * @param {Object=} params List of extra params to append to the URL.
* @return {string} The complete URL.
*/
-function feUrl(url, prefix = '') {
+function feUrl(url, prefix = '', params) {
// Add cache param.
url = feCached('https://news.google.com' + prefix + '/swg/_/ui/v1' + url);
@@ -4484,6 +4487,10 @@ function feUrl(url, prefix = '') {
url = addQueryParam(url, 'jsmode', boqJsMode);
}
+ for (const param in params) {
+ url = addQueryParam(url, param, params[param]);
+ }
+
return url;
}
@@ -4501,7 +4508,7 @@ function feCached(url) {
*/
function feArgs(args) {
return Object.assign(args, {
- '_client': 'SwG 0.1.22.161',
+ '_client': 'SwG 0.1.22.163',
});
}
@@ -4687,6 +4694,8 @@ class PayStartFlow {
{
forceRedirect:
this.deps_.config().windowOpenMode == WindowOpenMode.REDIRECT,
+ // basic flow does not support native.
+ forceDisableNative: paySwgVersion == '2',
}
);
return Promise.resolve();
@@ -5284,10 +5293,6 @@ class OffersFlow {
ViewSubscriptionsResponse,
this.startNativeFlow_.bind(this)
);
- activityIframeView.on(
- EntitlementsResponse,
- this.handleEntitlementsResponse_.bind(this)
- );
return this.dialogManager_.openView(activityIframeView);
});
@@ -5718,7 +5723,7 @@ class ActivityPorts$1 {
'analyticsContext': context.toArray(),
'publicationId': pageConfig.getPublicationId(),
'productId': pageConfig.getProductId(),
- '_client': 'SwG 0.1.22.161',
+ '_client': 'SwG 0.1.22.163',
'supportsEventManager': true,
},
args || {}
@@ -6566,7 +6571,7 @@ class AnalyticsService {
context.setTransactionId(getUuid());
}
context.setReferringOrigin(parseUrl(this.getReferrer_()).origin);
- context.setClientVersion('SwG 0.1.22.161');
+ context.setClientVersion('SwG 0.1.22.163');
context.setUrl(getCanonicalUrl(this.doc_));
const utmParams = parseQueryString(this.getQueryString_());
@@ -9867,14 +9872,9 @@ class Toast {
animate_(callback) {
const wait = this.animating_ || Promise.resolve();
return (this.animating_ = wait
- .then(
- () => {
- return callback();
- },
- () => {
- // Ignore errors to make sure animations don't get stuck.
- }
- )
+ .then(() => callback())
+ // Ignore errors to make sure animations don't get stuck.
+ .catch(() => {})
.then(() => {
this.animating_ = null;
}));
@@ -10005,6 +10005,92 @@ const AnalyticsEventToEntitlementResult = {
[AnalyticsEvent.IMPRESSION_PAYWALL]: EntitlementResult.LOCKED_PAYWALL,
};
+/**
+ * @param {!string} eventCategory
+ * @param {!string} eventAction
+ * @param {!string} eventLabel
+ * @param {!boolean} nonInteraction
+ * @returns {!Object}
+ */
+const createGoogleAnalyticsEvent = (
+ eventCategory,
+ eventAction,
+ eventLabel,
+ nonInteraction
+) => ({
+ eventCategory,
+ eventAction,
+ eventLabel,
+ nonInteraction,
+});
+
+/** @const {!Object} */
+const AnalyticsEventToGoogleAnalyticsEvent = {
+ [AnalyticsEvent.IMPRESSION_OFFERS]: createGoogleAnalyticsEvent(
+ 'NTG paywall',
+ 'paywall modal impression',
+ '',
+ true
+ ),
+ [AnalyticsEvent.IMPRESSION_CONTRIBUTION_OFFERS]: createGoogleAnalyticsEvent(
+ 'NTG membership',
+ 'offer impressions',
+ '',
+ true
+ ),
+
+ [AnalyticsEvent.ACTION_OFFER_SELECTED]: createGoogleAnalyticsEvent(
+ 'NTG paywall',
+ 'click',
+ '',
+ false
+ ),
+ [AnalyticsEvent.ACTION_SWG_SUBSCRIPTION_MINI_PROMPT_CLICK]: createGoogleAnalyticsEvent(
+ 'NTG subscription',
+ 'marketing modal click',
+ '',
+ false
+ ),
+ [AnalyticsEvent.IMPRESSION_SWG_SUBSCRIPTION_MINI_PROMPT]: createGoogleAnalyticsEvent(
+ 'NTG subscription',
+ 'marketing modal impression',
+ '',
+ true
+ ),
+ [AnalyticsEvent.ACTION_SWG_CONTRIBUTION_MINI_PROMPT_CLICK]: createGoogleAnalyticsEvent(
+ 'NTG membership',
+ 'marketing modal click',
+ '',
+ false
+ ),
+ [AnalyticsEvent.IMPRESSION_SWG_CONTRIBUTION_MINI_PROMPT]: createGoogleAnalyticsEvent(
+ 'NTG membership',
+ 'membership modal impression',
+ '',
+ true
+ ),
+};
+
+/** @const {!Object} */
+const SubscriptionSpecificAnalyticsEventToGoogleAnalyticsEvent = {
+ [AnalyticsEvent.ACTION_PAYMENT_COMPLETE]: createGoogleAnalyticsEvent(
+ 'NTG subscription',
+ 'submit',
+ 'success',
+ false
+ ),
+};
+
+/** @const {!Object} */
+const ContributionSpecificAnalyticsEventToGoogleAnalyticsEvent = {
+ [AnalyticsEvent.ACTION_PAYMENT_COMPLETE]: createGoogleAnalyticsEvent(
+ 'NTG membership',
+ 'submit',
+ 'success',
+ false
+ ),
+};
+
/**
* Converts a propensity event enum into an analytics event enum.
* @param {!Event|string} propensityEvent
@@ -10036,6 +10122,24 @@ function analyticsEventToEntitlementResult(event) {
return AnalyticsEventToEntitlementResult[event];
}
+/**
+ * Converts an analytics event enum into a Google Analytics event object.
+ * @param {?AnalyticsEvent} event
+ * @param {string} subscriptionFlow
+ * @returns {?Object}
+ */
+function analyticsEventToGoogleAnalyticsEvent(event, subscriptionFlow) {
+ let gaEvent = null;
+ if (subscriptionFlow) {
+ if (subscriptionFlow == SubscriptionFlows.SUBSCRIBE) {
+ gaEvent = SubscriptionSpecificAnalyticsEventToGoogleAnalyticsEvent[event];
+ } else if (subscriptionFlow == SubscriptionFlows.CONTRIBUTE) {
+ gaEvent = ContributionSpecificAnalyticsEventToGoogleAnalyticsEvent[event];
+ }
+ }
+ return gaEvent || AnalyticsEventToGoogleAnalyticsEvent[event];
+}
+
/**
* Copyright 2020 The Subscribe with Google Authors. All Rights Reserved.
*
@@ -11146,24 +11250,6 @@ class FetchResponse {
));
}
- /**
- * Reads the xhr responseXML.
- * @return {!Promise}
- * @private
- */
- document_() {
- assert(!this.bodyUsed, 'Body already used');
- this.bodyUsed = true;
- assert(
- this.xhr_.responseXML,
- 'responseXML should exist. Make sure to return ' +
- 'Content-Type: text/html header.'
- );
- return /** @type {!Promise} */ (Promise.resolve(
- assert(this.xhr_.responseXML)
- ));
- }
-
/**
* Drains the response and returns a promise that resolves with the response
* ArrayBuffer.
@@ -11319,6 +11405,62 @@ class XhrFetcher {
}
}
+/**
+ * Copyright 2021 The Subscribe with Google Authors. All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS-IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+class GoogleAnalyticsEventListener {
+ /**
+ * @param {!./deps.DepsDef} deps
+ */
+ constructor(deps) {
+ /** @private @const {!Window} */
+ this.win_ = deps.win();
+
+ /** @private @const {!./client-event-manager.ClientEventManager} */
+ this.eventManager_ = deps.eventManager();
+ }
+
+ /**
+ * Start listening to client events
+ */
+ start() {
+ this.eventManager_.registerEventListener(
+ this.handleClientEvent_.bind(this)
+ );
+ }
+
+ /**
+ * Listens for new events from the events manager and logs appropriate events to Google Analytics.
+ * @param {!../api/client-event-manager-api.ClientEvent} event
+ */
+ handleClientEvent_(event) {
+ // Bail immediately if ga function doesn't exist in Window.
+ if (typeof this.win_.ga != 'function') {
+ return;
+ }
+ const gaEvent = analyticsEventToGoogleAnalyticsEvent(
+ event.eventType,
+ event.additionalParameters?.subscriptionFlow
+ );
+ if (gaEvent) {
+ this.win_.ga('send', 'event', gaEvent);
+ }
+ }
+}
+
/**
* Copyright 2018 The Subscribe with Google Authors. All Rights Reserved.
*
@@ -15382,7 +15524,7 @@ class PayClient {
'disableNative',
// The page cannot be iframed at this time. May be relaxed later
// for AMP and similar contexts.
- this.win_ != this.top_()
+ options.forceDisableNative || this.win_ != this.top_()
);
let resolver = null;
const promise = new Promise((resolve) => (resolver = resolve));
@@ -16255,6 +16397,7 @@ class ConfiguredRuntime {
* @param {{
* fetcher: (!Fetcher|undefined),
* configPromise: (!Promise|undefined),
+ * enableGoogleAnalytics: (boolean|undefined),
* }=} integr
* @param {!../api/subscriptions.Config=} config
* @param {!{
@@ -16308,6 +16451,15 @@ class ConfiguredRuntime {
/** @private @const {!Callbacks} */
this.callbacks_ = new Callbacks();
+ // Start listening to Google Analytics events, if applicable.
+ if (integr.enableGoogleAnalytics) {
+ /** @private @const {!GoogleAnalyticsEventListener} */
+ this.googleAnalyticsEventListener_ = new GoogleAnalyticsEventListener(
+ this
+ );
+ this.googleAnalyticsEventListener_.start();
+ }
+
// WARNING: DepsDef ('this') is being progressively defined below.
// Constructors will crash if they rely on something that doesn't exist yet.
/** @private @const {!../components/activities.ActivityPorts} */
@@ -16823,6 +16975,11 @@ class ConfiguredRuntime {
});
entitlements.consume(onCloseDialog);
}
+
+ /** @override */
+ showBestAudienceAction() {
+ warn('Not implemented yet');
+ }
}
export { AnalyticsEvent, ClientEvent, ClientEventManagerApi, ConfiguredRuntime, DeferredAccountCreationResponse, Entitlement, Entitlements, EventOriginator, Fetcher, FilterResult, PurchaseData, SubscribeResponse, UserData };