MediaWiki:Centralnotice-template-pcoombe 2024 11 23 reducedLocalizeData m sm
<style> /* css variables */ .frb {
color-scheme: normal; color-scheme: light; --wmui-base100: #fff; --wmui-base90: #f8f9fa; --wmui-base80: #eaecf0; --wmui-base70: #c8ccd1; --wmui-base50: #a2a9b1; --wmui-base30: #72777d; --wmui-base20: #54595d; --wmui-base10: #202122; --wmui-base0: #000; --wmui-accent: #36c; --wmui-accent-light: #eaf3ff; --wmui-accent-dark: #2a4b8d; --wmui-red: #d73333; --wmui-red-light: #fee7e6; --wmui-red-dark: #b32424; --wmui-green: #00af89; --wmui-green-light: #d5fdf4; --wmui-green-dark: #14866d; --wmui-yellow: #fc3; --wmui-yellow-light: #fef6e7; --wmui-yellow-dark: #ac6600; --frb-primary: #900; --frb-primary-light: #fee7e6; --frb-primary-dark: var(--frb-primary); --frb-body: var(--wmui-base0); --frb-link: var(--wmui-accent); --frb-link-hover: #447ff5; --frb-main-background: var(--wmui-base100); --frb-message-background: #308557; --frb-message-border: #266a46; --frb-fieldset-background: var(--wmui-base100); --frb-header-background: var(--wmui-base100); --frb-message: var(--wmui-base100); --frb-muted: var(--wmui-base20); --frb-muted-hover: var(--wmui-base0); --frb-radio: var(--wmui-accent); --frb-button: var(--wmui-base90); --frb-button-border: var(--wmui-base50); --frb-button-hover: var(--wmui-base100); --frb-button-border-hover: var(--wmui-base50); --frb-button-focus: var(--wmui-base90); --frb-button-border-focus: var(--wmui-base50); --frb-button-selected: var(--wmui-accent-dark); --frb-button-border-selected: #7d8389; --frb-button-text: var(--wmui-base0); --frb-button-selected-text: var(--wmui-base100); --frb-submit: var(--wmui-accent); --frb-submit-border: var(--wmui-accent); --frb-submit-hover: #447ff5; --frb-submit-border-hover: #447ff5; --frb-error: var(--wmui-red-dark); /* dark because it can appear on a colored background */ --frb-nag-background: var(--wmui-base100); --frb-nag-border: #4e6cc0; --frb-cta-background: #f9dde9; --frb-dialog-backdrop: #ffffffa6; --frb-dialog-button: #f8f9fa; --frb-dialog-button-border: #a2a9b1; --frb-dialog-button-text: #007de2; --frb-dialog-button-hover: #eaf3ff; --frb-dialog-button-border-hover: #a2a9b1; --frb-dialog-button-text-hover: #007de2; --frb-optin-no: var(--wmui-red-light); --frb-optin-yes: var(--wmui-green-light);
}
/* darkmode */ html.skin-theme-clientpref-night .frb {
color-scheme: dark; --frb-primary: #900; --frb-primary-light: #fee7e6; --frb-primary-dark: var(--frb-primary); --frb-body: var(--wmui-base100); --frb-link: #95a0d8; --frb-link-hover: #aab2e0; --frb-main-background: transparent; --frb-message-background: #292b39; --frb-message-border: #40424e; --frb-fieldset-background: #0c0e17; --frb-header-background: transparent; --frb-message: var(--wmui-base100); --frb-muted: var(--wmui-base50); --frb-muted-hover: var(--wmui-base80); --frb-radio: var(--wmui-base0); --frb-button: #9a9eb6; --frb-button-border: #9a9eb6; --frb-button-hover: #677dc8; --frb-button-border-hover: #677dc8; --frb-button-focus: #677dc8; --frb-button-border-focus: #677dc8; --frb-button-selected: #677dc8; --frb-button-border-selected: #677dc8; --frb-button-text: var(--wmui-base0); --frb-button-selected-text: var(--wmui-base100); --frb-submit: #677dc8; --frb-submit-border: #677dc8; --frb-submit-hover: #aab2e0; --frb-submit-border-hover: #aab2e0; --frb-error: var(--wmui-red); --frb-nag-background: #223461; --frb-nag-border: #4e6cc0; --frb-cta-background: #e38c8c; --frb-dialog-backdrop: #000000a6; --frb-dialog-button: #9a9eb6; --frb-dialog-button-border: var(--frb-dialog-button); --frb-dialog-button-text: var(--wmui-base0); --frb-dialog-button-hover: #677dc8; --frb-dialog-button-border-hover: var(--frb-dialog-button-hover); --frb-dialog-button-text-hover: var(--wmui-base100); --frb-optin-no: var(--wmui-red-dark); --frb-optin-yes: var(--wmui-green-dark);
}
@media (prefers-color-scheme: dark) {
/* automatic mode */ html.skin-theme-clientpref-os .frb { color-scheme: dark; --frb-primary: #900; --frb-primary-light: #fee7e6; --frb-primary-dark: var(--frb-primary); --frb-body: var(--wmui-base100); --frb-link: #95a0d8; --frb-link-hover: #aab2e0; --frb-main-background: transparent; --frb-message-background: #292b39; --frb-message-border: #40424e; --frb-fieldset-background: #0c0e17; --frb-header-background: transparent; --frb-message: var(--wmui-base100); --frb-muted: var(--wmui-base50); --frb-muted-hover: var(--wmui-base80); --frb-radio: var(--wmui-base0); --frb-button: #9a9eb6; --frb-button-border: #9a9eb6; --frb-button-hover: #677dc8; --frb-button-border-hover: #677dc8; --frb-button-focus: #677dc8; --frb-button-border-focus: #677dc8; --frb-button-selected: #677dc8; --frb-button-border-selected: #677dc8; --frb-button-text: var(--wmui-base0); --frb-button-selected-text: var(--wmui-base100); --frb-submit: #677dc8; --frb-submit-border: #677dc8; --frb-submit-hover: #aab2e0; --frb-submit-border-hover: #aab2e0; --frb-error: var(--wmui-red); --frb-nag-background: #223461; --frb-nag-border: #4e6cc0; --frb-cta-background: #e38c8c; --frb-dialog-backdrop: #000000a6; --frb-dialog-button: #9a9eb6; --frb-dialog-button-border: var(--frb-dialog-button); --frb-dialog-button-text: var(--wmui-base0); --frb-dialog-button-hover: #677dc8; --frb-dialog-button-border-hover: var(--frb-dialog-button-hover); --frb-dialog-button-text-hover: var(--wmui-base100); --frb-optin-no: var(--wmui-red-dark); --frb-optin-yes: var(--wmui-green-dark); }
}
/* Hide nag when editor overlay enabled, or reference drawer open */ .overlay-enabled #frb-nag, .has-drawer--with-scroll-locked #frb-nag {
display: none !important;
}
/* Resets */ .frb * {
margin: 0; padding: 0; border: 0; font: inherit; font-size: 100%; vertical-align: baseline; background: none;
}
.frb button {
cursor: pointer;
}
/* Box-sizing */ .frb, .frb *, .frb *:before, .frb *:after {
-moz-box-sizing: border-box; -webkit-box-sizing: border-box; box-sizing: border-box;
}
.frb input[type="radio"], .frb input[type="number"], .frb input[type="email"] {
appearance: none; -webkit-appearance: none; -moz-appearance: none;
}
.frb input[type="number"] {
background-color: transparent; -moz-appearance:textfield;
}
.frb input[type="number"]::-webkit-outer-spin-button, .frb input[type="number"]::-webkit-inner-spin-button {
-webkit-appearance: none; margin: 0;
}
.frb frb-amt, .frb-replaced {
white-space: nowrap;
}
/* Hide when printed */ @media print {
.frb { display: none !important; }
}
@media (prefers-reduced-motion: reduce) {
.frb, .frb * { transition: none; }
}
/* Typography
*/
/*Base font*/ .frb {
font-family: system-ui, -apple-system,BlinkMacSystemFont, "Segoe UI", Roboto, "Oxygen-Sans", Ubuntu, Cantarell, Lato, "Helvetica Neue", Helvetica, Arial, sans-serif; font-size: 16px; line-height: 1.5; /*24px @16px*/
}
.frb-error {
display: none; line-height: 1.25; /*20px @16px*/ font-weight: 400; margin: 4px 0; color: var(--frb-error); text-align: center;
}
- frb-inline legend,
.frb-other-txt, .frb-optin-no-prompt {
font-size: 14px; line-height: 1.2857142857; /*18px @14px*/
}
@media all and (min-width: 480px) {
.frb-other-txt { font-size: 15px; line-height: 1.2666666667; /*19px @15px*/ }
}
- frb-nag {
font-size: 15px; line-height: 1.2; /*18px @15px*/
}
@media all and (min-width: 720px) {
#frb-nag { font-size: 17px; }
}
.frb-submit {
font-size: 18px; line-height: 1.2222222222; /*22px @18px*/
}
.frb-btn, .frb-label {
font-size: 15px; line-height: 1;
}
@media all and (min-width: 375px) {
.frb-btn, .frb-label { font-size: 16px; }
}
.frb-ptf {
line-height: 1.25; /*20px @16px*/
}
/* In-article banner styles
*/
- frb-inline {
display: table; position: relative; background: var(--frb-main-background); color: var(--frb-body); margin-top: 14px; margin-left: -16px; margin-right: -16px;
}
.frb-inline-border {
position: relative; padding: 10px 10px 6px; background-color: var(--frb-fieldset-background); border: 5px solid var(--frb-primary); box-shadow: 2px 2px 6px 0px rgba(0,0,0,0.15); margin: 0 10px;
}
.frb-inline-message {
display: flex; flex-wrap: wrap; justify-content: space-between; align-items: flex-start;
}
.frb-inline-svg-container {
display: flex; flex: 0 0 60px; max-width: 60px; height: 60px; width: 60px; background: var(--frb-primary); justify-content: center; align-items: center; float: left; margin: 0 15px 5px 0;
}
.frb-inline-svg-container svg {
width: 40px;
}
.frb-inline-svg-container svg path {
fill: var(--wmui-base100);
}
.frb-message-wrapper {
flex: 0 1 auto; max-width: 100%; display: flex; align-items: center;
}
/* consistent responsive sizing */
@media (max-width: 536px) {
.frb-message-wrapper { height: 162px; }
}
@media (max-width: 450px) {
.frb-message-wrapper { height: 184px; }
}
@media (max-width: 393px) {
.frb-message-wrapper { height: 207px; }
}
@media (max-width: 364px) {
.frb-message-wrapper { height: 229px; }
}
@media (max-width: 344px) {
.frb-message-wrapper { height: 252px; }
}
@media (max-width: 310px) {
.frb-message-wrapper { height: 274px; }
}
@media (max-width: 293px) {
.frb-message-wrapper { height: 297px; }
}
.frb-message-flex-container {
max-width: 100%; height: 100%; display: flex; align-items: center;
}
.frb-inline-message-text {
font-size: 15px; font-weight: 600; line-height: 1.5; display: block; margin-bottom: 0.25em;
}
.frb-step-2-message {
font-size: 15px; font-weight: 400; line-height: 1.5; display: block; margin-bottom: 0.25em;
}
.frb-inline-message .frb-icon-info {
height: 16px; margin-bottom: -2px; margin-right: 1px;
}
.frb-icon-info circle {
fill: var(--frb-primary);
}
.frb-icon-info path {
fill: var(--wmui-base100);
}
.frb-inline-message p:first-of-type {
margin-top: 0;
}
.frb-form {
position: relative; margin-top: 0; padding-bottom: 8px;
}
.frb-methods, .frb-amounts, .frb-frequency, .frb-optin {
margin-top: 1em; width: calc(100% + 8px); margin-left: -4px; margin-right: -4px;
}
.frb-form ul {
display: flex; flex-wrap: wrap; width: 100%; padding: 0;
}
.frb-form ul.frb-content-list {
margin-left: 20px; width: calc(100% - 20px);
}
.frb-form ul.frb-content-list li {
margin-bottom: 5px;
}
/* --- Form legends --- */
.frb-form legend {
margin: 0; color: var(--frb-muted); text-align: center; width: 100%;
}
.frb-form fieldset.frb-haserror .error-highlight {
color: var(--frb-error);
}
.frb-form legend {
font-weight: bold;
}
/* --- Common Button Styles --- */
.frb-btn, .frb-label {
display: flex; justify-content: center; align-items: center; background-color: var(--frb-button); color: var(--frb-button-text); border: 1px solid var(--frb-button-border); border-radius: 2px; padding: 2px 4px; min-height: 54px; outline: 0; text-align: center; cursor: pointer; font-weight: bold; transition: background 100ms, color 100ms, border-color 100ms, box-shadow 100ms;
} .frb-btn:hover, .frb-label:hover {
background-color: var(--frb-button-hover); color: var(--frb-body); border-color: var(--frb-button-border-hover);
} .frb-btn:active, .frb-label:active {
background-color: #d9d9d9; color: var(--frb-body); border-color: #7d8389;
}
.frb-btn:focus, .frb-label:focus, .frb-form input[type="radio"]:focus + .frb-btn, .frb-form input[type="radio"]:focus + .frb-label {
border-color: var(--frb-button-border-focus); box-shadow: inset 0 0 0 1px var(--frb-button-border-focus);
}
- frb-form input[type="radio"]:checked + .frb-btn,
- frb-form input[type="radio"]:checked + .frb-label {
background-color: var(--frb-button-selected); color: var(--wmui-base100); border-color: var(--frb-button-border-selected);
}
.frb-payment-options input[type="radio"]:checked + .frb-label svg.white-on-select {
filter: brightness(0) invert(1);
}
/* Disabled states */ .frb-form input:disabled + label {
opacity: 0.4 !important; cursor: default !important;
}
/* Submit/Continue buttons (blue background) */ .frb-submit {
display: block; width: 100%; margin-top: 12px; padding: 17px 6px; font-weight: bold; color: rgba(84,89,93,0.2); background-color: var(--wmui-base100); border: 1px solid var(--frb-button-border-hover); cursor: default; border-radius: 2px; transition: background-color 0.5s ease; opacity: .5;
}
.frb-submit.active, .frb-rml-form .frb-submit {
color: var(--wmui-base100); background-color: var(--frb-submit); border-color: var(--frb-submit-border); cursor: pointer; opacity: 1;
} .frb-submit.active:hover, .frb-rml-form .frb-submit:hover {
background-color: var(--frb-submit-hover); border-color: var(--frb-submit-border-hover);
}
.frb-submit-label-monthly {
display: none;
} .frb-submit-label-now {
display: inline;
} .form-monthly .frb-submit-label-monthly {
display: inline;
} .form-monthly .frb-submit-label-now {
display: none;
}
.frb-submit-txt-once { display: inline; } .form-monthly .frb-submit-txt-once { display: none; }
.frb-submit-txt-monthly { display: none; } .form-monthly .frb-submit-txt-monthly { display: inline; }
/* Hide radio buttons. Based on http://jqueryui.com/button/#radio */ .frb-ptf-checkbox, .frb-form input[type="radio"] {
position: absolute; overflow: hidden; height: 1px; width: 1px; clip: rect(0 0 0 0); border: 0; margin: -1px; padding: 0;
}
/* --- Amount buttons layout --- */
.frb-amounts ul li, .frb-frequency ul li, .frb-optin ul li {
display: block; width: 50%; padding: 4px; margin: 0;
}
/* Larger screen layout, 3 amount buttons per row */ @media (min-width: 375px) {
.frb-amounts ul li { flex: 0 0 33.33%; max-width: 33.33%; }
.frb-amounts ul li.frb-button--other { flex: 0 0 66.67%; max-width: 66.67%; }
}
/* --- Other amount --- */
.frb-button--other label {
display: block;
}
/* Other amount field */ .frb-other-txt, .frb-other-input {
line-height: 1; text-align: left;
}
.frb-other-txt {
display: block; text-align: center; margin-top: 1px; margin-bottom: 3px;
}
.frb-other-input {
width: 100%; max-width: 120px; border: none; text-align: center !important; font-weight: bold; color: var(--frb-body); box-shadow: 0 2px 0 0 #222; text-align: right; border-radius: 0; /* Needed for iOS */
}
.frb-button--other .frb-btn {
padding: 6px;
}
.frb-button--other .frb-label {
padding: 2px 6px 6px;
}
.frb-radio:checked + .frb-other-txt, .frb-radio:checked + .frb-btn .frb-other-input {
color: var(--wmui-base100);
}
.frb-radio:checked + .frb-btn .frb-other-input {
box-shadow: 0 2px 0 0 var(--wmui-base100);
}
.frb-input {
background: var(--wmui-base100); padding: 12px; margin: 0; color: #000; border: 1px solid var(--frb-button-border); border-radius: 2px;
}
.frb-input:focus {
outline: 0; border-color: var(--frb-button-border-focus); box-shadow: inset 0 0 0 1px var(--frb-button-border-focus);
}
.frb-input.frb-haserror {
border-color: var(--frb-error); box-shadow: inset 0 0 0 1px var(--frb-error);
}
/* --- Pay the fee --- */ .frb-ptf {
margin-left: 2px; width: calc(100% - 6px); padding-top: 9px; padding-bottom: 6px;
}
.frb-ptf-fee {
white-space: nowrap;
}
.frb-ptf-checkbox:focus + .frb-ptf-label .frb-ptf-img {
box-shadow: inset 0 0 0 2px var(--frb-button-border-focus), inset 0 0 0 2px var(--wmui-base100);
}
.frb-ptf-checkbox:focus + .frb-ptf-label .frb-ptf-img {
border-radius: 5px;
}
.frb-ptf-checkbox + .frb-ptf-label .frb-ptf-img {
display: inline-block; margin-bottom: -4px; width: 32px; height: 32px; background-image: url('https://upload.wikimedia.org/wikipedia/donate/b/b1/Wmf-frb-checkbox.png'); background-size: 64px; background-repeat: no-repeat; background-position: 0 0;
}
.frb-ptf-checkbox:checked + .frb-ptf-label .frb-ptf-img {
background-position: -32px 0;
}
.frb-ptf-label {
display: flex; align-items: center; cursor: pointer;
}
.frb-ptf-cell {
display: table-cell; vertical-align: middle;
}
.frb-ptf-cell:first-child {
padding-left: 2px;
}
body.rtl .frb-ptf-cell:first-child {
padding-left: 0; padding-right: 2px;
}
.frb-ptf-cell:nth-child(2) {
padding-left: 12px;
}
body.rtl .frb-ptf-cell:nth-child(2) {
padding-left: 0; padding-right: 12px;
}
/* --- Payment method buttons layout --- */
/* Always horizontal */ .frb-payment-options {
display: flex; width: 100%; flex-wrap: wrap;
}
.frb-payment-options .frb-button {
display: inline-block; flex: 1 0 0; padding: 4px; margin: 0;
}
/* 5 or 6 methods, go to 2 rows */ .frb-payment-options .frb-button:first-child:nth-last-child(5), .frb-payment-options .frb-button:first-child:nth-last-child(5) ~ .frb-button, .frb-payment-options .frb-button:first-child:nth-last-child(6), .frb-payment-options .frb-button:first-child:nth-last-child(6) ~ .frb-button {
min-width: 33%;
}
/* If there are 5 buttons, make the first one of the wider ones */ .frb-payment-options .frb-button:first-child:nth-last-child(5) {
min-width: 50%;
}
/* Mostly so bank transfer methods don't overspill */ .frb-methods .frb-label {
font-size: 14px;
}
/* -- Credit card logos -- */
.frb-cc-logo-wrapper {
display: none; margin: 0 auto; font-size: 0; /* Remove spacing between icons */
}
.frb-pm-cc svg {
width: 28px; height: 18px; margin: 2px; display: none;
}
/* Responsive styling for small screens */
@media (max-width: 374px) {
.frb-methods .frb-pm-cc .frb-label { padding: 2px; }
.frb-payment-options .frb-button.frb-pm-cc:first-child:nth-last-child(4) svg, .frb-payment-options .frb-button.frb-pm-cc:first-child:nth-last-child(4) ~ .frb-button.frb-pm-cc svg, .frb-payment-options .frb-button.frb-pm-cc:first-child:nth-last-child(5) svg, .frb-payment-options .frb-button.frb-pm-cc:first-child:nth-last-child(5) ~ .frb-button.frb-pm-cc svg, .frb-payment-options .frb-button.frb-pm-cc:first-child:nth-last-child(6) svg, .frb-payment-options .frb-button.frb-pm-cc:first-child:nth-last-child(6) ~ .frb-button.frb-pm-cc svg { width: 28px; height: 17px; margin: 1px; }
}
@media (max-width: 300px) {
.frb-methods .frb-pm-cc svg, .frb-payment-options .frb-button.frb-pm-cc:first-child:nth-last-child(4) svg, .frb-payment-options .frb-button.frb-pm-cc:first-child:nth-last-child(4) ~ .frb-button.frb-pm-cc svg, .frb-payment-options .frb-button.frb-pm-cc:first-child:nth-last-child(5) svg, .frb-payment-options .frb-button.frb-pm-cc:first-child:nth-last-child(5) ~ .frb-button.frb-pm-cc svg, .frb-payment-options .frb-button.frb-pm-cc:first-child:nth-last-child(6) svg, .frb-payment-options .frb-button.frb-pm-cc:first-child:nth-last-child(6) ~ .frb-button.frb-pm-cc svg { width: 20px; height: 15px; margin: 1px; }
}
.frb-cctypes-vmad .frb-cc-logo-wrapper, .frb-cctypes-vmaj .frb-cc-logo-wrapper, .frb-cctypes-vma .frb-cc-logo-wrapper, .frb-cctypes-vm .frb-cc-logo-wrapper {
display: block;
}
.frb-cctypes-vmad .frb-pm-cc-label, .frb-cctypes-vmaj .frb-pm-cc-label, .frb-cctypes-vma .frb-pm-cc-label, .frb-cctypes-vm .frb-pm-cc-label {
display: none;
}
.frb-cctypes-vmad .frb-cc-logo-visa, .frb-cctypes-vmad .frb-cc-logo-mastercard, .frb-cctypes-vmad .frb-cc-logo-amex, .frb-cctypes-vmad .frb-cc-logo-discover,
.frb-cctypes-vmaj .frb-cc-logo-visa, .frb-cctypes-vmaj .frb-cc-logo-mastercard, .frb-cctypes-vmaj .frb-cc-logo-amex, .frb-cctypes-vmaj .frb-cc-logo-jcb,
.frb-cctypes-vma .frb-cc-logo-visa, .frb-cctypes-vma .frb-cc-logo-mastercard, .frb-cctypes-vma .frb-cc-logo-amex,
.frb-cctypes-vm .frb-cc-logo-visa, .frb-cctypes-vm .frb-cc-logo-mastercard {
display: inline-block;
}
/* Payment method buttons logo sizing */ .frb-payment-options .frb-logo-payments {
max-width: 100%;
}
/* --- Top bar --- */
.frb-inline-topbar {
width: 100%; text-align: left; background-color: var(--frb-main-background); color: var(--frb-body); display: inline-block; z-index: 888; font-weight: 600; font-size: 15.5px; line-height: 1.125; /* 18px @16px */ position: relative; padding: 0 0 10px;
}
.frb-logo-payments--paypal-usd {
margin-bottom: -4px; /* visual tweak */
}
.frb-methods legend, .frb-methods .frb-label {
transition: all .2s ease-in-out;
}
/* --- Close and RML Options --- */
.frb-inline-bottombar {
text-align: center; display: flex; justify-content: center; align-items: center; flex-wrap: wrap;
}
.frb-footer-button {
color: var(--frb-muted); font-size: 12px; text-transform: uppercase; padding: 8px 10px; height: 45px;
}
.frb-footer-button:hover {
color: var(--frb-muted-hover);
}
/* Close button icon */ .frb-close-x {
margin-bottom: -3px; width: 13px; height: 13px;
} .frb-close-x {
stroke: currentColor;
}
/* RML link */
- frb-inline .frb-rml-link {
color: var(--frb-link); font-weight: bold;
}
- frb-inline .frb-rml-link:hover,
- frb-inline .frb-rml-link:focus {
color: var(--frb-link-hover);
}
/* RML clock icon */ .frb-inline-rml-icon {
margin-bottom: -2px; width: 13px; height: 13px;
} .frb-inline-rml-icon path {
fill: currentColor;
} .frb-inline-rml-icon circle {
stroke: currentColor;
}
/* --- Smallprint --- */
.frb-footer {
width: 100%; margin-top: 24px; margin-bottom: 8px;
}
.frb-smallprint {
font-size: 12px; line-height: 1.5; color: var(--frb-muted); font-weight: normal;
}
.frb-smallprint a {
color: var(--frb-muted); text-decoration: underline
}
.frb-smallprint a:hover, .frb-smallprint a:focus {
color: var(--frb-muted-hover); text-decoration: underline
}
- frb-inline .recurring-details {
display: none;
}
/* Bottom "nag" banner styles
*/
- frb-nag {
z-index: 100; position: fixed; left: 2.5%; bottom: 0; width: 95%; display: block; color: var(--frb-body); background-color: var(--frb-nag-background); box-shadow: 0 0 15px 0 rgba(0,0,0,.7); border-radius: 10px 10px 0 0; padding: 16px; text-align: center; font-weight: bold; cursor: pointer;
}
- frb-nag:hover {
text-decoration: none;
}
- frb-nag .frb-icon-info {
height: 19px; width: 19px; margin-bottom: -3px; padding-right: 4px;
}
body.rtl #frb-nag .frb-icon-info {
padding-right: 0; padding-left: 4px;
}
- frb-nag .frb-btn {
display: inline-block; padding: 8px 10px; min-height: 44px; font-size: 14px;
}
.frb-nag-message {
vertical-align: middle; margin-bottom: 10px; padding: 0 20px;
} .frb-nag-message:hover {
text-decoration: underline;
}
.frb-nag-close {
position: absolute; display: block; top: -6px; right: -6px; width: 44px; height: 44px; padding: 10px; cursor: pointer; transition: all .25s ease-in-out;
} body.rtl .frb-nag-close {
right: auto; left: 0;
} .frb-nag-close g {
fill: var(--frb-muted);
}
.frb-nag-close:active {
-moz-transform: scale(1.05); -ms-transform: scale(1.05); -webkit-transform: scale(1.05); transform: scale(1.05);
}
.frb-icon-nag-close {
width: 21px; height: 21px;
}
/* give the footer padding so it's visible above the nag */ .minerva-footer {
padding-bottom: 140px;
}
/*!--- Focus styles ----*/
/*Outline reset*/ .frb-submit:focus,
- frb-amt-other-input:focus,
.email_input:focus {
outline: 0;
}
.frb-submit:focus, .frb-form input[type="radio"]:checked:focus + label, .email_input:focus,
- frb-form .frb-amt-other.is-focused .frb-btn,
- frb-form .frb-button--is-focused .frb-btn {
border-color: var(--frb-button-border-focus); box-shadow: inset 0 0 0 2px var(--frb-button-border-focus), inset 0 0 0 3px var(--wmui-base100);
}
/* Email optin */ .frb-optin-no-prompt {
display: none; clear: both; padding: 6px 8px; border: 1px solid var(--wmui-red-dark); background-color: var(--frb-optin-no); border-radius: 2px; font-weight: normal; margin: 4px;
}
.frb-optin-no-prompt.is-positive {
border-color: var(--wmui-green-dark); background-color: var(--frb-optin-yes); font-weight: bold;
}
.frb-optin-no-prompt__yes {
display: none;
}
.frb-optin-no-prompt__no {
display: block;
}
.frb-optin-no-prompt.is-positive .frb-optin-no-prompt__yes {
display: block;
}
.frb-optin-no-prompt.is-positive .frb-optin-no-prompt__no {
display: none;
}
.frb-optin-legal {
font-size: 14px; padding: 0 4px;
}
/* Back button */ .frb-back {
cursor: pointer; position: absolute; left: -10px; top: -10px; color: var(--wmui-base30); width: 45px; height: 45px;
} .frb-back:hover {
color: var(--frb-muted-hover);
}
.frb-back path {
stroke: currentColor;
} .frb-back rect {
fill: currentColor;
}
.frb-icon-back {
height: 13px; width: 20px;
}
/* STEP 2 UPSELL*/
.frb-upsell, .frb-step-monthly-diff-amt .frb-amt-monthly {
width: calc(100% + 8px) !important; transition: background-color 0.5s ease; padding: 10px 4px; text-align: center;
}
.frb-upsell {
margin-top: 1em; padding: 0 35px;
}
.frb-step-monthly-diff-amt .frb-amt-monthly {
display: block; padding: 0 4px 10px 4px;
}
.frb-upsell-cta, .frb-upsell-ty {
font-size: 17px; line-height: 1.3; font-weight: bold; text-align: center;
}
.frb-icon-heart path {
fill: #900;
}
- monthly-support-text {
max-width: 400px; margin: 0.5em auto;
}
.frb-upsell-color, .frb-step-monthly-diff-amt .frb-amt-monthly label {
display: block; font-size: 15px; line-height: 1.3; font-weight: normal; margin: .5em 0;
}
.frb-monthly-diff-amt-link {
display: block; font-size: 15px; line-height: 1.3; color: var(--frb-link); margin: 8px auto; padding: 12px; text-align: center; cursor: pointer; font-weight: bold;
}
.frb-monthly-diff-amt-link:hover {
text-decoration: underline;
}
- frb-amt-monthly-other-input {
text-align: center; font-size: 18px;
}
.frb-step-monthly-diff-amt {
display: none; text-align: center;
}
/* New RML Nag Styles */
- frb-nag .frb-btn-btxt {
background-color: var(--frb-primary); border: 1px solid var(--frb-primary); color: var(--wmui-base100); transition: background 100ms, color 100ms; text-transform: uppercase;
}
- frb-nag .frb-btn-btxt:active {
background-color: var(--wmui-base0); color: var(--wmui-base100);
}
- frb-nag.active .frb-nag-action {
display: none;
}
/* --- Disable I already donated --- */ .frb.frb-iad-disabled .frb-iad {
display: none;
}
/* CTA first */
/* TODO: have these re-use other button styles */
.frb-cta-first .frb-btn-wrapper {
margin: auto !important; width: auto !important;
}
.frb-cta-first { text-align: center; }
- frb-inline .frb-cta-first ul.frb-btn-wrapper {
margin: auto auto 6px; display: inline-block;
}
.frb-form fieldset.frb-cta-first .frb-btn-wrapper li {
display: inline-block; flex: none; margin: 0 !important;
}
.frb .frb-cta-first .frb-btn-cta .frb-btn-cta-label{
position: relative; padding-right: 15px; font-weight: 600;
}
.frb .frb-cta-first .frb-btn-cta .frb-btn-cta-label::after {
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 6.7 12'%3E%3Cpath d='M.9 0L0 .9 5.1 6 0 11.1l.9.9 5.5-5.5c.3-.3.3-.7 0-.9L.9 0z' fill='%23fff'/%3E%3C/svg%3E"); content: ' '; position: absolute; top: 52.5%; right: 0; width: 7px; height: 12px; -moz-transform: translateY(-50%); -ms-transform: translateY(-50%); -webkit-transform: translateY(-50%); transform: translateY(-50%);
}
.frb .frb-cta-first .frb-submit.frb-btn-cta {
margin-top: 0; text-align: center; padding: 10px; background-color: #36c; border-color: #36c; color: #fff; position: relative; font-size: 16px; height: 45px;
}
.frb .frb-cta-first .frb-submit.frb-btn-cta:hover {
background-color: #447ff5; border-color: #447ff5;
}
.frb .frb-cta-first .frb-btn.frb-btn-simple {
background-color: transparent; border-color: transparent; color: var(--frb-link); font-weight: normal; padding: 10px; margin-left: 2px; font-size: 15px;
}
@media (max-width: 300px) {
.frb .frb-cta-first .frb-btn.frb-btn-simple { padding: 10px; margin: 0; }
}
.frb .frb-cta-first .frb-btn.frb-btn-simple:hover {
text-decoration: underline; color: #447ff5;
}
.frb .frb-cta-first .frb-btn.frb-btn-simple:focus {
box-shadow: none; color: #447ff5; text-decoration: underline;
}
.frb-updating-time {
font-variant-numeric: tabular-nums; white-space: nowrap;
}
/* wmf identity */
.frb-wmf-identity {
position: relative; clear: both; padding: 0 10px; color: var(--frb-body); line-height: 1.3; display: flex; justify-content: center; margin: 5px 0 -2px;
}
.frb-wmf-identity-logo {
flex: 0 0 85px; max-width: 85px; display: flex; align-items: center; margin: 0 10px 0 0;
}
.frb-wmf-identity-logo img {
width: 100%; max-width: 100%;
}
.frb-wmf-identity-message {
flex: 0 1 auto; align-items: center; padding-left: 5px; color: var(--frb-muted); font-size: 13px; line-height: 1.3; margin: 5px;
}
.frb-submit-txt-donate { display: none; } .frb-submit-txt-once { display: inline; } .frb-submit-txt-monthly { display: none; } .form-monthly .frb-submit-txt-once { display: none; } .form-monthly .frb-submit-txt-monthly { display: inline; }
/* -- Dialogs -- */
.frb-dialog {
display: none; /* needed for unsupported browsers */ background: var(--frb-fieldset-background); border: 1px solid var(--frb-button-border); border-radius: 2px; box-shadow: 0 2px 2px #0003; width: 90%; max-width: 600px; padding: 40px 20px;
}
.frb-dialog[open] {
display: block;
}
.frb-dialog::backdrop {
background: var(--frb-dialog-backdrop);
}
.frb-dialog-back {
border: none; background: none; margin: 0; padding: 0; cursor: pointer; position: absolute; top: 20px; left: 20px; width: 20px; height: 20px; opacity: 0.5;
} .frb-dialog-back:hover {
opacity: 1;
}
.frb-dialog-title {
font-size: 17px; color: var(--frb-body); font-weight: bold; border: 0; text-align: center; margin-bottom: 20px;
}
.frb-dialog-text {
font-size: 15px; line-height: 1.44; margin-bottom: 20px; max-width: 530px;
}
@media (min-width: 720px) {
.frb-dialog { padding: 40px; }
}
/* -- I already donated -- */
.frb-iad-buttons {
display: flex; flex-wrap: wrap; justify-content: center;
}
.frb-iad-buttons button {
width: 100%; margin: 8px 0; padding: 10px 15px; display: block; border-radius: 2px; border: solid 1px var(--frb-dialog-button-border); background-color: var(--frb-dialog-button); font-size: 16px; font-weight: bold; color: var(--frb-dialog-button-text); cursor: pointer;
}
.frb-iad-buttons button:hover{
background-color: var(--frb-dialog-button-hover); border-color: var(--frb-dialog-button-border-hover); color: var(--frb-dialog-button-text-hover);
}
.frb-iad-buttons button:focus{
background-color: var(--frb-dialog-button-hover); border-color: var(--frb-dialog-button-border-hover); color: var(--frb-dialog-button-text-hover);
}
@media (min-width: 720px) {
#frb-dialog-iad { text-align: center; }
.frb-iad-buttons button { margin: 0 8px; width: 165px; }
}
/* --- Maybe later --- */
.frb-rml-disabled .frb-rml, .frb-rml-disabled .frb-rml-link, .frb-rml-disabled #nag-rml-btn {
display: none !important;
}
.frb-rml-form-legend {
display: block; margin: 0 0 4px; padding: 0; font-weight: normal; text-align: inherit; font-size: 14px; line-height: 1.2142857143; color: var(--frb-muted);
}
.frb-rml-form input {
width: 100%; padding: 4px 8px; border: 1px solid var(--wmui-base50); border-radius: 2px; color: var(--frb-body); font-size: 16px; height: 45px; margin-bottom: 20px;
}
- frb-rml-email.frb-haserror {
border-color: var(--frb-error) !important; box-shadow: inset 0 0 0 1px var(--frb-error) !important;
}
.frb-error-invalidemail {
margin: 2px 0 0 !important;
}
.frb-dialog .frb-submit {
margin: 0; width: 100%;
}
.frb-dialog .frb-smallprint {
margin-top: 20px;
}
.frb-rml-ty {
text-align: center; font-size: 15px; line-height: 1.44;
}
/* --- Monthly Pitch --- */
/* latin-ext */ @font-face {
font-family: 'Caveat Brush'; font-style: normal; font-weight: 400; font-display: block; src: url('https://upload.wikimedia.org/wikipedia/donate/5/51/Caveat-brush-v6-latin-ext-regular.woff2') format('woff2'); unicode-range: U+0100-024F, U+0259, U+1E00-1EFF, U+2020, U+20A0-20AB, U+20AD-20CF, U+2113, U+2C60-2C7F, U+A720-A7FF;
} /* latin */ @font-face {
font-family: 'Caveat Brush'; font-style: normal; font-weight: 400; font-display: block; src: url('https://upload.wikimedia.org/wikipedia/donate/7/75/Caveat-brush-v6-latin-regular.woff2') format('woff2'); unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
.frb-monthly-pitch, .frb-monthly-pitch-thanks {
font-size: 18px; line-height: 1.2; color: var(--frb-link); padding-top: 8px !important; padding-bottom: 15px; font-family: 'Caveat Brush', auto; text-align: center; margin: auto;
}
.frb-monthly-pitch {
max-width: 100%; padding: 0 65px 15px 20px; text-align: right; margin: 0; position: relative;
}
.frb-monthly-pitch-arrow {
width: 18px; height: 18px; position: absolute; right: 40px; margin: 0; top: 50%; transform: translateY(-50%); margin-top: -9px;
}
.frb-monthly-pitch-thanks {
display: none; text-align: center; padding-right: 32px; padding-left: 24px; max-width: 310px; margin: auto;
}
.frb-monthly-pitch-thanks-heart {
width: 26px; height: 26px; margin-left: 0; margin-right: 3px; margin-top: -2px; float: left;
}
.form-monthly .frb-monthly-pitch { display: none; } .form-monthly .frb-monthly-pitch-thanks { display: block; }
.form-monthly-disabled .frb-monthly-pitch {
opacity: 0.4;
}
/* --- Night Mode Adjustments --- */
html.skin-theme-clientpref-night .frb-radio:hover + .frb-label svg.white-on-select, html.skin-theme-clientpref-night .frb-radio:focus + .frb-label svg.white-on-select {
filter: brightness(0) invert(1);
}
@media (prefers-color-scheme: dark) {
html.skin-theme-clientpref-os .frb-radio:hover + .frb-label svg.white-on-select, html.skin-theme-clientpref-os .frb-radio:focus + .frb-label svg.white-on-select { filter: brightness(0) invert(1); }
} </style>
<dialog id="frb-dialog-rml" class="frb frb-dialog">
<button class="frb-dialog-close frb-dialog-back skin-invert"> <svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 20 16'><g fill='none' fill-rule='evenodd' transform='translate(1 1)'><path stroke='#000' stroke-linecap='round' stroke-linejoin='round' stroke-width='1.778' d='M7.181 13.285L.753 7 7.181.715'></path><rect fill='#000' width='18.182' height='1.778' x='.818' y='6.111' rx='.889'></rect></g></svg> </button>
<form method="post" action="https://www.pages04.net/wikimedia/remind/Form?sp_source={{{banner}}}" class="frb-rml-form" id="frb-rml-form"> <input type="hidden" name="formSourceName" value="StandardForm" /> <input type="hidden" name="sp_exp" value="yes" /> <input type="hidden" name="rml_source" value="{{{banner}}}" /> <input type="hidden" name="rml_group" value="dsk_sm" /> <input type="hidden" name="rml_country" value="" /> <input type="hidden" name="rml_language" value="" /> <input type="hidden" name="rml_submitDate" value="" /> <input type="hidden" name="rml_segment" value="" />
<label class="frb-rml-form-legend" for="frb-rml-email">{{{FR2015_translations,remind-me-donor-email}}}</label> <input type="email" name="Email" id="frb-rml-email" dir="ltr" autocomplete="email" autofocus />
<button class="frb-submit active" id="frb-rml-submit" type="submit">{{{FR2015_translations,remind-me-submit}}}</button>
{{{FR2015_translations,legal-non-us}}}
</form>
</dialog>
<dialog id="frb-dialog-iad" class="frb frb-dialog">
<button class="frb-dialog-close frb-dialog-back skin-invert"> <svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 20 16'><g fill='none' fill-rule='evenodd' transform='translate(1 1)'><path stroke='#000' stroke-linecap='round' stroke-linejoin='round' stroke-width='1.778' d='M7.181 13.285L.753 7 7.181.715'></path><rect fill='#000' width='18.182' height='1.778' x='.818' y='6.111' rx='.889'></rect></g></svg> </button>
{{{FR2015_translations,iad-subtitle}}}
</dialog>
<script> var frb = frb || {};
/* jshint maxerr: 600 */ frb.amounts = frb.amounts || {};
// Hard minimum amounts that can be given // From https://github.com/wikimedia/wikimedia-fundraising-SmashPig/blob/master/PaymentData/ReferenceData/CurrencyRates.php // Updated 2023-12-12 frb.amounts.minimums = { 'USD' : 1, 'CAD' : 1.36, 'AUD' : 1.52, 'NZD' : 1.63, 'GBP' : 0.80, 'EUR' : 0.93 };
frb.amounts.options7 = { // Big English 'USD' : [2.75, 10, 15, 25, 50, 75, 100], 'CAD' : [2.75, 10, 15, 25, 50, 75, 100], 'AUD' : [2.75, 10, 15, 25, 50, 75, 100], 'NZD' : [2.75, 10, 15, 25, 50, 75, 100], 'GBP' : [2.75, 10, 15, 25, 50, 75, 100], 'EUR' : [2.75, 10, 15, 25, 50, 75, 100] };
// "Average" donation frb.amounts.averages = { 'USD' : 13, 'CAD' : 12, 'AUD' : 11, 'NZD' : 12, 'GBP' : 6, 'EUR' : 8 };
// 'If everyone gave X'. Mostly the same as first asks option. frb.amounts.ifEveryone = { // Big English 'USD' : 2.75, 'CAD' : 2.75, 'AUD' : 2.75, 'NZD' : 2.75, 'GBP' : 2.75, 'EUR' : 2.75 };
// Minimum fee/PTF amounts. Default is 0.35. // Updated 2018-07-05 based on Ppena's feedback // Updated 2019-05-21 to approx 0.35 USD equivalent frb.amounts.feeMinimums = {};
// If one-time amount <= left amount, suggest right amount for monthly // If changing these, please update spreadsheet // https://docs.google.com/spreadsheets/d/1z36zi8EegPLAvR5FYAgwz8ywKZ50QNB82SpwpTdk-xQ/edit#gid=1258723967 frb.amounts.monthlySuggest = { 'USD' : [ // also EUR, GBP, CAD, AUD, NZD [ 2.74, 0 ], [ 9, 1.75 ], [ 12, 2 ], [ 15, 2.5 ], [ 18, 3 ], [ 21, 3.5 ], [ 24, 4 ], [ 27, 4.5 ], [ 30, 5 ], [ 33, 5.5 ], [ 36, 6 ], [ 39, 6.5 ], [ 42, 7 ], [ 45, 7.5 ], [ 48, 8 ], [ 51, 8.5 ], [ 54, 9 ], [ 57, 9.5 ], [ 60, 10 ], [ 63, 10.5 ], [ 66, 11 ], [ 69, 11.5 ], [ 72, 12 ], [ 75, 12.5 ], [ 102, 17 ], [ 250, 25 ], [ 499, 50 ], [ Infinity, 0 ] ] }; frb.amounts.monthlySuggest.EUR = frb.amounts.monthlySuggest.USD; frb.amounts.monthlySuggest.GBP = frb.amounts.monthlySuggest.USD; frb.amounts.monthlySuggest.CAD = frb.amounts.monthlySuggest.USD; frb.amounts.monthlySuggest.AUD = frb.amounts.monthlySuggest.USD; frb.amounts.monthlySuggest.NZD = frb.amounts.monthlySuggest.USD;
frb.currencyFormats = { 'USD' : '$\t', 'CAD' : { 'fr' : '\t $', 'default' : '$\t' }, 'AUD' : '$\t', 'NZD' : '$\t', 'GBP' : '£\t', 'EUR' : { 'en' : '€\t', 'cy' : '€\t', 'ga' : '€\t', 'mt' : '€\t', 'nl' : '€ \t', 'lv' : '€ \t', 'tr' : '€ \t', 'default' : '\t €' } };
// Check in user language first, then fall back to English frb.countryNames = { 'en' : { 'US' : 'the United States', 'CA' : 'Canada', 'GB' : 'the UK', 'IE' : 'Ireland', 'AU' : 'Australia', 'NZ' : 'New Zealand', }, 'es' : { 'US' : 'en los Estados Unidos' }, 'fr' : { 'CA' : 'au Canada' } };
/* Most of the translations are actually using "in COUNTRY" or similar to account for grammar differences. So this makes English do the same, and allows us to use a clearer %in-country% variable, while avoiding breaking old content using %country%.
- /
frb.inCountryNames = JSON.parse( JSON.stringify( frb.countryNames ) ); // deep copy frb.inCountryNames.en = { 'US' : 'in the United States', 'CA' : 'in Canada', 'GB' : 'in the UK', 'IE' : 'in Ireland', 'AU' : 'in Australia', 'NZ' : 'in New Zealand', };
frb.dayNames = { 'en' : [ 'Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday' ], 'es' : [ 'domingo', 'lunes', 'martes', 'miércoles', 'jueves', 'viernes', 'sábado' ], 'fr' : [ 'dimanche', 'lundi', 'mardi', 'mercredi', 'jeudi', 'vendredi', 'samedi' ] };
// "This fooday" translations. Needed for some languages where gender varies and "this" must agree frb.dayNamesThis = { 'en' : [ 'this Sunday', 'this Monday', 'this Tuesday', 'this Wednesday', 'this Thursday', 'this Friday', 'this Saturday' ], };
// Insert any localize data overrides here
/* jshint maxerr: 600 */ /* MediaWiki:FundraisingBanners/CoreJS-2018.js
* Core code for banner forms, with new inline error messages */
var frb = frb || {};
/**
* Test for general ES6 and <dialog> support * * Checks for arrow functions, default parameters, NodeList.prototype.forEach(), <dialog> support * Should be roughly Chrome 51+, Firefox 98+, Edge 79+, Safari 15.4+ * Based on https://gist.github.com/bendc/d7f3dbc83d0f65ca0433caf90378cd95 * @return {boolean} */
frb.supportedBrowser = function() { try { new Function('(a = 0) => a'); document.querySelectorAll('.frb').forEach(a => a); if ( typeof HTMLDialogElement === 'function' ) { return true; } else { return false; } } catch (err) { return false; } }();
if ( !mw.centralNotice.adminUi ) { // T262693 frb.loadedTime = Date.now(); frb.didSelectAmount = false; frb.optinRequiredCountries = [ 'AR', 'AT', 'BE', 'BR', 'CL', 'CO', 'CZ', 'DK', 'ES', 'FR', 'GB', 'GR', 'HU', 'IE', 'IT', 'IL', 'LU', 'LV', 'MX', 'NL', 'NO', 'PE', 'PL', 'PT', 'RO', 'SE', 'SK', 'UA', 'UY' ]; frb.optinRequired = frb.optinRequiredCountries.indexOf(mw.centralNotice.data.country) !== -1; frb.maxUSD = 25000; frb.reduceMotion = window.matchMedia('(prefers-reduced-motion: reduce)').matches; }
// Keyboard shortcut to go from banner preview to editor - Ctrl+Shift+E if ( mw.config.get('wgUserName') ) { if ( mw.config.get('wgUserName').match(/\(WMF\)/) ) { window.addEventListener('keydown', function(e) { if ( e.ctrlKey && e.shiftKey && e.keyCode === 69 ) { window.open( 'https://meta.wikimedia.org/wiki/Special:CentralNoticeBanners/Edit/' + mw.centralNotice.data.banner ); } }); } }
/**
* Main function to submit to paymentswiki * * @param {Object} options * - method (required) * - submethod (optional) * - gateway (optional) * - skipValidation (optional boolean, for pp-usd. Not yet implemented.) * @param {Boolean} isEndowment - deprecated, set frb.isEndowment instead */
frb.submitForm = function( options, isEndowment ) {
var url = new URL('https://payments.wikimedia.org/index.php/Special:GatewayChooser'); var params = {};
if ( !frb.validateForm( options ) ) { frb.extraData.validateError = 1; // Flag they had an error, even if fixed later return false; // Error, bail out of submitting }
if ( frb.isDarkMode() ) { frb.extraData.darkMode = 1; }
// Skip form chooser for Venmo if ( options.method === 'venmo' && options.gateway !== 'gravy' ) { url = new URL('https://payments.wikimedia.org/index.php/Special:BraintreeGateway'); }
// Form selection data params.payment_method = options.method; if ( options.submethod ) { params.payment_submethod = options.submethod; } if ( options.gateway ) { params.gateway = options.gateway; } if ( options.variant ) { params.variant = options.variant; } params.recurring = frb.getRecurring();
if ( params.recurring && params.variant && params.variant.match( /monthlyConvert/ ) ) { // Post-payments monthly convert makes no sense if it's already recurring // Avoid things like T312905 delete params.variant; }
params.currency = frb.getCurrency(mw.centralNotice.data.country) || 'USD';
params.uselang = mw.centralNotice.data.uselang || 'en'; params.country = mw.centralNotice.data.country || 'XX';
if ( params.uselang === 'pt' && params.country === 'BR' ) { params.uselang = 'pt-br'; } if ( params.uselang === 'es' && ( params.country === 'AR' || params.country === 'CL' || params.country === 'CO' || params.country === 'MX' || params.country === 'PE' || params.country === 'UY' || params.country === 'US' ) ) { params.uselang = 'es-419'; }
// dLocal override for South Africa if ( params.payment_method === 'cc' && params.country === 'ZA' ) { params.gateway = 'astropay'; }
// Amount var amount = frb.getAmount(); if ( $('#frb-ptf-checkbox').prop('checked') ) { amount = amount + frb.calculateFee(amount); frb.extraData.ptf = 1; } params.amount = amount;
// Email optin if ( frb.optinRequired && $('input[name="opt_in"]').length > 0 ) { var opt_inValue = $('input[name="opt_in"]:checked').val(); params.opt_in = opt_inValue; // frb.validateForm() already checked it's 1 or 0 }
// Tracking info if ( isEndowment || frb.isEndowment ) { params.wmf_medium = 'endowment'; params.appeal = 'EndowmentQuote'; } else { params.wmf_medium = 'sitenotice'; } params.wmf_campaign = mw.centralNotice.data.campaign || 'test'; params.wmf_source = frb.buildTrackingSource(params);
frb.extraData.time = Math.round( (Date.now() - frb.loadedTime)/1000 );
if ( !$.isEmptyObject( frb.extraData ) ) { params.wmf_key = frb.buildTrackingKey( frb.extraData ); }
// Link to Banner History if enabled var mixins = mw.centralNotice.getDataProperty( 'mixins' ); if ( mixins && mixins.bannerHistoryLogger ) { params.bannerhistlog = mw.centralNotice.bannerHistoryLogger.id; }
for ( var key of Object.keys( params ) ) { url.searchParams.set( key, params[key] ); }
// Set a cookie with current ___location so we can return here from TY page mw.loader.using( [ 'mediawiki.cookie', 'mediawiki.util' ] ).then( function () { // Exclude URL parameters like banner, but cope with paths like /w/index.php?title=Foo var returnToUrl = window.___location.origin + mw.util.getUrl(); mw.cookie.set( 'fundraising_returnTo', returnToUrl, { expires: 300, prefix: , ___domain: '.wikipedia.org', secure: true } ); });
if ( mixins && mixins.bannerHistoryLogger ) { mw.centralNotice.bannerHistoryLogger.ensureLogSent().always(function() { frb.goToPayments( url ); }); } else { frb.goToPayments( url ); }
};
frb.goToPayments = function( url ) { if ( window.top !== window.self ) { // banner is in a frame, open payments in a new tab window.open( url.toString() ); } else { window.___location.href = url.toString(); } };
/**
* Check the form for errors. * * Called on submission, can also be called on input * * @param {object} options * @return {boolean} Whether form is error-free */
frb.validateForm = function( options ) { var error = false;
/* Reset all errors */ $('.frb-haserror').removeClass('frb-haserror'); $('.frb-error').hide();
if ( !options.method ) { error = true; $('.frb-methods').addClass('frb-haserror'); $('.frb-error-method').show(); }
if ( !frb.validateAmount() ) { error = true; }
/* Email optin */ if ( frb.optinRequired && $('.frb-optin').is(':visible') ) { var opt_inValue = $('input[name="opt_in"]:checked').val(); if ( opt_inValue !== '1' && opt_inValue !== '0' ) { $('.frb-optin').addClass('frb-haserror'); $('.frb-error-optin').show(); error = true; } }
return !error; };
/**
* Check if selected amount is valid i.e. a positive number, between minimum and maximum. * If not, show an error and return false. */
frb.validateAmount = function() {
var amount = frb.getAmount(), currency = frb.getCurrency( mw.centralNotice.data.country ), minAmount = frb.amounts.minimums[ currency ], maxAmount = Math.round( frb.maxUSD * minAmount ); // Math.round to account for floating point math errors: https://phabricator.wikimedia.org/T246262
if ( amount === null || isNaN(amount) || amount <= 0 || amount < minAmount ) { $('fieldset.frb-amounts').addClass('frb-haserror'); $('.frb-error-bigamount').hide(); $('.frb-error-smallamount').show(); return false; } else if ( amount > Math.round( maxAmount ) ) { $('fieldset.frb-amounts').addClass('frb-haserror'); $('.frb-error-bigamount').show(); return false; } else { $('fieldset.frb-amounts').removeClass('frb-haserror'); $('.frb-error-smallamount, .frb-error-bigamount').hide(); return true; } };
/**
* Build the wmf_source for analytics. * * Own function so it can be overriden for weird tests * * @param {Object} params * @return {string} wmf_source */
frb.buildTrackingSource = function(params) {
var wmf_source; var fullDottedPaymentMethod = params.payment_method; if ( params.recurring ) { fullDottedPaymentMethod = 'r' + fullDottedPaymentMethod; } if ( params.payment_submethod ) { fullDottedPaymentMethod = fullDottedPaymentMethod + '.' + params.payment_submethod; }
wmf_source = mw.centralNotice.data.banner;
// Keeping opt-in in wmf_source for safety for now // Eventually remove it, or move to wmf_key? if ( params.opt_in ) { wmf_source += '_optIn' + params.opt_in; }
wmf_source += '.no-LP.' + fullDottedPaymentMethod;
return wmf_source; };
/**
* Build a string for wmf_key from extra tracking data * * @param {Object} data * @return {string} wmf_key */
frb.buildTrackingKey = function(data) { var dataArray = []; for (var key in data) { if (data.hasOwnProperty(key)) { dataArray.push( key + '_' + data[key] ); } } return dataArray.join('~'); };
/**
* Determine if we should show recurring choice on step 2 * * NOTE 2023-12-07: we don't currently use this for step 2, since there are no * banners where users select method before frequency. However it is used by * frb.shouldShowMonthlyConvert() * * @param {Object} options Including method and optional gateway * @param {String} country * @return {boolean} */
frb.shouldShowRecurring = function( options, country ) {
if ( frb.isEndowment ) { return false; } if ( frb.noRecurringCountries.indexOf( country ) !== -1 ) { // Defined in LocalizeJS-2017.js return false; } if ( options.method === undefined ) { return true; // Show if a method hasn't been selected yet } if ( [ 'cc', 'venmo', 'apple', 'google' ].indexOf( options.method ) !== -1 ) { return true; } if ( options.method === 'paypal' ) { if ( [ 'AR', 'BR', 'CL', 'CO', 'MX', 'PE', 'UY' ].includes( country ) ) { return false; } else { return true; } } // Adyen iDEAL if ( options.submethod === 'rtbt_ideal' ) { return true; } // SEPA if ( options.submethod === 'sepadirectdebit' ) { return true; } if ( options.submethod === 'upi' || options.submethod === 'paytmwallet' ) { return true; } return false; };
/* Is recurring method selected? This function can be overriden for different forms */ frb.getRecurring = function() { // Can't use simple form.frequency.value, doesn't work in IE var selected = $('#frb-form input[name="frequency"]:checked').val(); return selected === 'monthly'; };
/* Return amount selected */ frb.getAmount = function() { var form = document.getElementById('frb-form'); var amount = null; frb.extraData.otherAmt = 0;
// If there are some amount radio buttons, then look for the checked one if (form.amount) { for (var i = 0; i < form.amount.length; i++) { if (form.amount[i].checked) { amount = form.amount[i].value; } } }
// Check the "other" amount box if (form.otherAmount.value !== ) { var otherAmount = form.otherAmount.value; otherAmount = otherAmount.replace(/[,.](\d)$/, ':$10'); otherAmount = otherAmount.replace(/[,.](\d)(\d)$/, ':$1$2'); otherAmount = otherAmount.replace(/[$£€¥,.]/g, ); otherAmount = otherAmount.replace(/:/, '.'); amount = otherAmount; frb.extraData.otherAmt = 1; }
amount = parseFloat(amount);
if ( isNaN(amount) ) { return 0; } else { return amount; }
};
/* Localize the amount errors. Call when initialising banner. */ frb.localizeErrors = function() { var currency = frb.getCurrency( mw.centralNotice.data.country ), language = mw.centralNotice.data.uselang, minAmount = frb.amounts.minimums[ currency ], maxAmount = Math.round( frb.maxUSD * minAmount ); // Math.round to account for floating point math errors: https://phabricator.wikimedia.org/T246262
$('.frb-error-smallamount').text( function( index, oldText ) { return oldText.replace( '$1', frb.formatCurrency(currency, minAmount, language) ); });
$('.frb-error-bigamount').text( function( index, oldText ) { // We cannot accept donations greater than $1 $2 through our website. Please contact our major gifts staff at $3. return oldText.replace( '$1', maxAmount ) .replace( '$2', currency ) .replace( '$3', 'benefactors@wikimedia.org' ); }); };
/**
* Shared code for amount input handling */
frb.initAmountOptions = function() {
// Reset "Other" input if user clicks a preset amount $('#frb-form [id^=frb-amt-ps]').click(function() { $('#frb-amt-other-input').val(); });
// Track if they selected and then later changed amount var checkAmountChange = function(e) { if ( frb.didSelectAmount ) { frb.extraData.changedAmt = 1; } // check if amount radio button is selected OR there is a value in the other amount if ( $('.frb-amounts input[type="radio"]:checked').val() !== 'Other' || $('#frb-amt-other-input').val().length > 0 ) { frb.didSelectAmount = true; } return; };
$('.frb-amounts input[type="radio"]').on('change', checkAmountChange); $('#frb-amt-other-input').on('focusout', checkAmountChange);
// Block typing non-numerics in input field, otherwise Safari allows them and then chokes // https://phabricator.wikimedia.org/T118741, https://phabricator.wikimedia.org/T173431 var blockNonNumeric = function(e) { // Allow special keys in Firefox if ((e.code == 'ArrowLeft') || (e.code == 'ArrowRight') || (e.code == 'ArrowUp') || (e.code == 'ArrowDown') || (e.code == 'Delete') || (e.code == 'Backspace')) { return; } var chr = String.fromCharCode(e.which); if ("0123456789., ".indexOf(chr) === -1) { return false; } }; $('#frb-amt-other-input').on('keypress', blockNonNumeric); $('#frb-amt-monthly-other-input').on('keypress', blockNonNumeric);
};
/**
* Calculate approximate transaction fee on given amount * * @param {number} amount * @return {number} Rounded to 2 decimal places */
frb.calculateFee = function(amount) { var currency = frb.getCurrency(mw.centralNotice.data.country), feeMultiplier = 0.04, feeMinimum = frb.amounts.feeMinimums[currency] || 0.35, feeAmount = amount * feeMultiplier;
if ( feeAmount < feeMinimum ) { feeAmount = feeMinimum; } return parseFloat(feeAmount.toFixed(2)); };
frb.updateFeeDisplay = function() { var currency = frb.getCurrency(mw.centralNotice.data.country), language = mw.centralNotice.data.uselang, amount, feeAmount, totalAmount;
amount = frb.getAmount(); feeAmount = frb.calculateFee(amount); if ( $('#frb-ptf-checkbox').prop('checked') ) { totalAmount = amount + feeAmount; } else { totalAmount = amount; }
var feeAmountFormatted = frb.formatCurrency(currency, feeAmount, language); $('.frb-ptf-fee').text(feeAmountFormatted);
var totalAmountFormatted = frb.formatCurrency(currency, totalAmount, language); $('.frb-ptf-total').text(totalAmountFormatted);
$('.frb-ptf').slideDown( frb.reduceMotion ? 0 : 400 ); };
/**
* Custom hide cookie function * * Purposely sets only for this ___domain. * CentralNotice builtin method seems buggy - see T270401 * * @param {string} reason Reason to store in the hide cookie * @param {number} duration Cookie duration, in seconds */
frb.altSetHideCookie = function ( reason, duration ) {
mw.loader.using( 'mediawiki.cookie' ).then( function () {
var cookieName = 'centralnotice_hide_fundraising', date = new Date(), hideData = { v: 1, created: Math.floor( date.getTime() / 1000 ), reason: reason };
// Re-use the same date object to set the cookie's expiry time date.setSeconds( date.getSeconds() + duration );
mw.cookie.set( cookieName, JSON.stringify( hideData ), { expires: date, path: '/', ___domain: 'wikipedia.org', prefix: } );
});
};
frb.showDonateLinkTooltip = function ( content ) { try { mw.loader.using( [ 'oojs-ui-core' ] ).done( function () {
let $donateLink = $( '#pt-sitesupport-2 a, #pt-sitesupport a, #n-sitesupport a, #p-donation a' ); $donateLink.attr( 'href', ( i, oldUrl ) => { let url = new URL( oldUrl, 'https://donate.wikimedia.org' ); // base needed because some links are protocol relative url.searchParams.delete( 'utm_source' ); // Until we have updated sidebar links url.searchParams.set( 'wmf_source', 'tooltipOnBannerClose' ); return url.toString(); });
let popupOptions = {
$content: $( '
' + content + '
' ),
padded: true, autoclose: true, align: 'forwards', autoFlip: false };
if ( document.querySelector( '#p-donation a' ) ) { // Minerva popupOptions.$floatableContainer = $( '.navigation-drawer' ); popupOptions.position = 'below'; } else if ( $( '#pt-sitesupport-2 a:visible' ).length > 0 ) { // Vector 2022 user tools popupOptions.$floatableContainer = $( '#pt-sitesupport-2 a' ); popupOptions.position = 'below'; } else if ( document.querySelector( '#pt-sitesupport a' ) ) { // Vector 2022 user tools collapsed in menu popupOptions.$floatableContainer = $( '#vector-user-links-dropdown' ); popupOptions.position = 'below'; } else if ( document.querySelector( '#vector-main-menu-dropdown #n-sitesupport a') ) { // Vector 2022 main menu (only when logged in, so mostly here for testing) popupOptions.$floatableContainer = $( '#vector-main-menu-dropdown' ); popupOptions.position = 'below'; } else if ( document.querySelector( '#n-sitesupport a' ) ) { // Legacy Vector (sidebar) popupOptions.$floatableContainer = $( '#n-sitesupport a' ); popupOptions.position = 'after'; }
let popup = new OO.ui.PopupWidget( popupOptions );
popup.$element.css('z-index', 5); // Fix so it shows above header $( document.body ).append( popup.$element ); popup.toggle( true );
setTimeout( () => { popup.$element.fadeOut( frb.fadeDuration ); }, 5000 ); } ); } catch (e) { console.log('Problem showing banner close tooltip'); } };
frb.showSidebarTooltip = frb.showDonateLinkTooltip; // Alias for old name
frb.isDarkMode = function() { let rootClasses = document.documentElement.classList, osDark = window.matchMedia('(prefers-color-scheme: dark)').matches; return rootClasses.contains( 'skin-theme-clientpref-night' ) || ( rootClasses.contains( 'skin-theme-clientpref-os' ) && osDark ); };
/**
* Determine if banner should be shown, and set correct data for impression logging * * @return {boolean} Show banner? */
frb.shouldShowBanner = function() {
mw.centralNotice.bannerData.hideResult = false;
/* Hide in unsupported browsers */ if ( !frb.supportedBrowser ) { mw.centralNotice.bannerData.hideResult = true; mw.centralNotice.bannerData.hideReason = 'browser'; }
/* Hide outside main namespace (except Main Page, for sites where it isn't in main namespace) */ if ( mw.config.get('wgNamespaceNumber') > 0 && !mw.config.get('wgIsMainPage') ) { mw.centralNotice.bannerData.hideResult = true; mw.centralNotice.bannerData.hideReason = 'namespace'; }
// Hide banner on sensitive articles // TODO - possibly add wgWikibaseItemId for multilingual support and resilience to moves? var hideTitles = [ 'Murder of Don Banfield', 'Asian News International', 'Asian News International vs. Wikimedia Foundation' ]; var pageTitle = mw.config.get('wgTitle'); if ( hideTitles.indexOf( pageTitle ) !== -1 ) { mw.centralNotice.bannerData.hideResult = true; mw.centralNotice.bannerData.hideReason = 'article'; }
/* Hide banner if on wrong site (desktop/mobile) in case wrong device settings were chosen */ var bannerName = mw.centralNotice.data.banner, skin = mw.config.get('skin'), siteName = mw.config.get('wgSiteName'); if ( ( bannerName.indexOf('_dsk_') !== -1 && skin === 'minerva' ) || ( bannerName.indexOf('_m_') !== -1 && skin !== 'minerva' ) || skin === 'wikimediaapiportal' || // workaround for T270308 siteName === 'Wikitech' ) { mw.centralNotice.bannerData.hideResult = true; mw.centralNotice.bannerData.hideReason = 'other'; console.warn('Hiding fundraising banner on wrong site (desktop/mobile)'); }
return !mw.centralNotice.bannerData.hideResult;
};
/* Debug function to highlight dynamically replaced elements */ frb.highlightReplacements = function() { $('.frb [class^="frb-replace"], .frb-ptf-fee, .frb-ptf-total, .frb-upsell-ask, frb-amt').css('background-color', '#fa0'); };
if ( !mw.centralNotice.adminUi ) { // T262693 /** * Provides alterImpressionData hook for CentralNotice * This info will be sent back with Special:RecordImpression * TODO: check if/when we can remove this (and RecordImpression) */ mediaWiki.centralNotice.bannerData.alterImpressionData = function( impressionData ) { // Returning true from this function indicates the banner was shown if (mediaWiki.centralNotice.bannerData.hideReason) { impressionData.reason = mediaWiki.centralNotice.bannerData.hideReason; } if (mediaWiki.centralNotice.bannerData.cookieCount) { impressionData.banner_count = mediaWiki.centralNotice.bannerData.cookieCount; }
return !mediaWiki.centralNotice.bannerData.hideResult; }; }
/* End of MediaWiki:FundraisingBanners/CoreJS-2018.js */ /* jshint maxerr: 600 */ /* == MediaWiki:FundraisingBanners/LocalizeJS-2022.js == */
/**
* Get the currency for a given country * * NOTE: The following currency mapping is WMF-specific based on payment * provider availability, NOT necessarily the official currency of the country * * @param {string} country code * @return {string} currency code */
frb.getCurrency = function(country) { switch ( country ) { // Big 6 case 'US': return 'USD'; case 'CA': return 'CAD'; case 'AU': return 'AUD'; case 'NZ': return 'NZD'; case 'GB': return 'GBP'; case 'IE': return 'EUR'; // Euro countries case 'AT': case 'BE': case 'ES': case 'FR': case 'GR': case 'IE': case 'IT': case 'LU': case 'LV': case 'NL': case 'PT': case 'SK': return 'EUR'; // Others case 'DK': return 'DKK'; case 'HU': return 'HUF'; case 'IL': return 'ILS'; case 'IN': return 'INR'; case 'JP': return 'JPY'; case 'MY': return 'MYR'; case 'NO': return 'NOK'; case 'PL': return 'PLN'; case 'CZ': return 'CZK'; case 'RO': return 'RON'; case 'SE': return 'SEK'; case 'UA': return 'UAH'; case 'ZA': return 'ZAR'; // Latin America case 'BR': return 'BRL'; case 'AR': return 'ARS'; case 'CL': return 'CLP'; case 'CO': return 'COP'; case 'MX': return 'MXN'; case 'PE': return 'PEN'; case 'UY': return 'UYU'; case 'CH': return 'CHF'; case 'LI': return 'CHF'; // Fall back to USD default: return 'USD'; } };
/**
* Format a currency value * * TODO: make this handle the ISO code overrides? * * @param {string} currency code. Leave undefined to get without symbol. * @param {number} amount * @param {string} language code * @return {string} formatted string e.g. '$3', '£5', '10 €' */
frb.formatCurrency = function(currency, amount, language) {
var locale, formatterOptions, formatter, fmAmount, supportsIntl;
if ( isNaN(amount) || amount === ) { // Not a number, it's probably the 'other' string or box // TODO: better way of doing this? fmAmount = amount; } else { // Check browser support try { supportsIntl = typeof window.Intl === 'object'; } catch (e) { supportsIntl = false; // T265396 }
if ( supportsIntl ) { // Use Intl for fancy number formatting - thousands separators etc locale = language + '-' + mw.centralNotice.data.country; if ( amount % 1 !== 0 ) { formatterOptions = { minimumFractionDigits: 2 }; } else { formatterOptions = {}; } formatter = new Intl.NumberFormat(locale, formatterOptions); } else { // Bad browser i.e. IE. Just do the basics: 2 decimal places if needed, or none formatter = {}; formatter.format = function(number) { if ( amount % 1 !== 0 ) { return number.toFixed(2); } else { return number.toString(); } }; } fmAmount = formatter.format(amount); }
// No symbol needed if ( currency === undefined ) { return fmAmount; }
// Better dive into the formatting object if ( frb.currencyFormats[currency] === undefined ) { return currency + ' ' + fmAmount; } if ( frb.currencyFormats[currency] instanceof Object ) { // not a string if ( frb.currencyFormats[currency][language] !== undefined ) { return frb.currencyFormats[currency][language].replace('\t', fmAmount); } return frb.currencyFormats[currency]['default'].replace('\t', fmAmount); }
return frb.currencyFormats[currency].replace('\t', fmAmount); };
/*
* Select the correct amount or array of amounts from object in "source" * * @param {Object} source - the amounts data object e.g. frb.amounts.options7, frb.amounts.averages * @param {string} currency - ISO code of currency * @param {string} country - ISO code of country (optional) * @return {array/number} - depending on source */
frb.pickAmounts = function(source, currency, country) {
if ( source[currency]['default'] ) { // we need to go deeper if ( source[currency][country] !== undefined ) { return source[currency][country]; } else { return source[currency]['default']; } } else { return source[currency]; } };
/* Credit card types so we can show the correct logos */ frb.cardTypes = { // Big 6 'US' : 'vmad', 'CA' : 'vma', 'GB' : 'vmaj', 'IE' : 'vmaj', 'AU' : 'vmaj', 'NZ' : 'vma', // Euro countries 'AT' : 'vmaj', 'BE' : 'vmaj', 'ES' : 'vmaj', 'FR' : 'vma', 'GR' : 'vma', 'IT' : 'vmaj', 'LU' : 'vmaj', 'LV' : 'vma', 'NL' : 'vmaj', 'PT' : 'vmaj', 'SK' : 'vmaj', // Others 'CZ' : 'vmad', 'DK' : 'vma', 'HU' : 'vma', 'IL' : 'vmad', 'JP' : 'vmaj', 'MY' : 'vmaj', 'NO' : 'vma', 'PL' : 'vma', 'RO' : 'vma', 'SE' : 'vma', 'UA' : 'vma', 'ZA' : 'vm', 'IN' : 'vmar', // dLocal - RuPay 'CH' : 'vma', 'LI' : 'vma' };
/**
* Should we show Apple Pay? * * Note there is a ~500ms delay in Safari when checking, so only call this if needed * * @param {string} country * @return {boolean} */
frb.shouldShowApplePay = function ( country ) { // https://support.apple.com/en-us/HT207957 - minus China mainland var appleCountries = [ 'ZA', 'AU', 'HK', 'JP', 'MO', 'NZ', 'SG', 'TW', 'AM', 'AT', 'AZ', 'BY', 'BE', 'BG', 'HR', 'CY', 'CZ', 'DK', 'EE', 'FO', 'FI', 'FR', 'GE', 'DE', 'GR', 'GL', 'GG', 'HU', 'IS', 'IE', 'IM', 'IT', 'KZ', 'JE', 'LV', 'LI', 'LT', 'LU', 'MT', 'MC', 'ME', 'NL', 'NO', 'PL', 'PT', 'RO', 'RU', 'SM', 'RS', 'SK', 'SI', 'ES', 'SE', 'CH', 'UA', 'GB', 'VA', 'CO', 'CR', 'BR', 'MX', 'BH', 'IL', 'PS', 'QA', 'SA', 'AE', 'CA', 'US' ]; if ( appleCountries.indexOf( country ) === -1 ) { return false; } if ( ___location.search.match('forceApplePay') ) { return true; } if ( window.ApplePaySession ) { if ( ApplePaySession.canMakePayments() ) { return true; } } return false; };
/**
* Display the correct payment methods for current country * * Methods should be labeled with class 'frb-pm-xxxx' * TODO: clean this function up more * * @param {string} country */
frb.localizeMethods = function(country) {
// Test country with *all the methods* if ( country === 'ZZ' ) { $('.frb-payment-options > div').show(); return; }
// Hide recurring completely for some countries and endowment if ( frb.isEndowment || frb.noRecurringCountries.indexOf(country) !== -1 ) { $('.frb-frequency, .recurring-details').hide(); }
// Remove any leftover WorldPay and Adyen $('.frb-pm-cc-wp').remove(); $('.frb-pm-cc-adyen').remove();
// Countries with no PayPal option var noPP = ['IN', 'RU', 'SG', 'AE', 'QA', 'OM', 'BD', 'BO', 'PA', 'PY', 'GT', 'JM', 'TT', 'DZ']; if ($.inArray(country, noPP) !== -1) { $('.frb-pm-pp').remove(); $('.frb-pm-pp-usd').remove(); }
// Countries with no PayPal for mobile only - https://phabricator.wikimedia.org/T173001 var noPPmobile = ['PH', 'ID', 'TH', 'KR', 'MY', 'VN']; var mobileRegex = /(_mob_|_ipd_|_m_)/; if ($.inArray(country, noPPmobile) !== -1) { if (mw.centralNotice.data.banner.search(mobileRegex) !== -1) { $('.frb-pm-pp').remove(); $('.frb-pm-pp-usd').remove(); } }
// Countries where PayPal must be in USD var ppUSD = ['BG', 'HR', 'LT', 'MK', 'RO', 'UA', 'SA', 'CN', 'ID', 'KR', 'KZ', 'MY', 'VN', 'AR', 'CL', 'DO', 'CO', 'NI', 'UY', 'ZA', 'BH', 'LB', 'VE', 'TR', 'IS', 'BA', 'MV', 'BB', 'BM', 'BZ', 'CR', 'CW', 'SX', 'HN', 'KN', 'DM', 'AG', 'LC', 'GD', 'FJ', 'TN', 'BJ', 'BF', 'CI', 'GW', 'ML', 'NE', 'SN', 'TG', 'BR', 'PE']; if ($.inArray(country, ppUSD) !== -1) { $('.frb-pm-pp').remove(); $('.frb-pm-pp-usd').show(); } else { $('.frb-pm-pp').show(); $('.frb-pm-pp-usd').remove(); }
// Show any extra local payment methods, or remove them if not needed var extrapaymentmethods = { 'amazon' : ['US'], // Note Amazon was removed from current best 2023-10-20 'bpay' : [], 'ideal' : ['NL'], 'bt' : ['AR', 'CO', 'CL', 'PE', 'MX', 'IN', 'ZA', 'CZ'], // Bank Transfer (dLocal/Adyen) 'cash' : ['MX', 'AR', 'PE', 'UY'], // 'Cash' methods (dLocal) 'pix' : ['BR'], 'boleto' : ['BR'], 'ach' : ['US'], 'trustly' : ['US'], 'sepa' : ['AT', 'BE', 'CY', 'DE', 'EE', 'ES', 'FR', 'GR', 'HR', 'IE', 'IT', 'LT', 'LU', 'LV', 'MT', 'NL', 'PT', 'SI', 'SK'] };
// Methods with different labels per country
var language = mw.config.get('wgUserLanguage'); var btTranslation = 'Bank Transfer';
if (language === 'pt') {
if (country === 'BR') { btTranslation = 'Transferência bancária'; }
} else if (language === 'es') {
if (country === 'CL') { btTranslation = 'WebPay'; } else if (country === 'CO') { btTranslation = 'PSE Pagos'; } else { btTranslation = 'Transferencia bancaria'; }
}
if (country === 'CZ') { if (language === 'en') { btTranslation = 'Online Banking'; } if (language === 'cs') { btTranslation = 'Internetové Bankovnictví'; } }
$( '.frb-pm-bt button, .frb-pm-bt label, button.frb-pm-bt' ).text( btTranslation );
for (var method in extrapaymentmethods) { var $methodbutton = $('.frb-pm-' + method); if ( $.inArray(country, extrapaymentmethods[method]) !== -1 && !frb.isEndowment ) { $methodbutton.show(); } else { $methodbutton.remove(); } }
// Google Pay - separated from extrapaymentmethods as we want to show on Endowment too var googlePayCountries = [ 'AE', 'AT', 'AR', 'AU', 'BE', 'BG', 'BR', 'CA', 'CH', 'CL', 'CO', 'CZ', 'DE', 'DK', 'EE', 'ES', 'FR', 'GB', 'GR', 'HK', 'HR', 'HU', 'IE', 'IL', 'IT', 'JP', 'LU', 'LV', 'MX', 'MY', 'NL', 'NO', 'NZ', 'OM', 'PE', 'PL', 'PT', 'QA', 'RO', 'RU', 'SA', 'SE', 'SG', 'SK', 'TH', 'TR', 'TW', 'UA', 'US', 'UY', 'VN', 'ZA' ]; if ( $.inArray(country, googlePayCountries) !== -1 ) { $('.frb-pm-google').show(); } else { $('.frb-pm-google').remove(); }
// Apple Pay if ( $('.frb-pm-applepay').length > 0 ) { if ( !frb.shouldShowApplePay( country ) ) { $('.frb-pm-applepay').remove(); } }
// Venmo var $venmo = $('.frb-pm-venmo'); if ( country === 'US' && $venmo.length > 0 ) { // From MediaWiki:FundraisingBanners/VenmoBrowserCheck.js if ( frb.isVenmoSupported() ) { $venmo.show(); } else { $venmo.remove(); } } else { $venmo.remove(); }
/* Add card types class to credit card button, so we can show correct logos */ if ( frb.cardTypes[country] ) { $('.frb-pm-cc').addClass('frb-cctypes-' + frb.cardTypes[country] ); } };
/**
* Check scheduled payment method outages and hide buttons if needed * * Data at https://meta.wikimedia.org/wiki/MediaWiki:FR2013/Resources/PaymentOutages.js * Methods should be labeled with class 'frb-pm-xxxx' * * @param {string} country code */
frb.checkMethodOutages = function(country) {
// TODO - can we load this a better way? /* This file can be used to schedule hiding of individual payment methods from banners
* e.g. if they have scheduled downtime. * * Valid methods are: * ideal, cc, pp, amazon, bpay, webmoney, cash, pp-usd * (most of the time it's 'ideal'...) * Can also limit outage to a specific country with country: "XX" (where XX is an ISO code) * * Note that in JavaScript dates the months (and only the months) start at 0. * Jan=0, Feb=1, Mar=2, Apr=3 etc. How hateful. * * Be sure to also update donatewiki if needed e.g. by commenting the method templates * found at https://donate.wikimedia.org/wiki/Template:2012FR/Form-section/Paymentmethods * */
var outages = [
{ start: new Date(Date.UTC(2016, 8, 18, 1)), end: new Date(Date.UTC(2016, 8, 18, 7)), method: "ideal" }
]; // jshint ignore:line var now = new Date();
for (var i = outages.length - 1; i >= 0; i--) { if ( now > outages[i].start && now < outages[i].end ) { if (outages[i].country === undefined || outages[i].country == country) { $('.frb-pm-' + outages[i].method).hide(); } } } };
/**
* Adjust the amount options and their labels * * Inputs should have id frb-amt-psX where X is the index number (starting from 1) * * @param {Object} source - object with amounts e.g. frb.amounts.options7 * @param {string} currency - currency code e.g. 'USD' * @param {string} country - country code e.g. 'FR' Some currencies can have different options per country. * @param {string} language - language code e.g. 'en' For symbol formatting * @param {boolean} useSymbols - use currency symbols on labels or not? (3 vs $3) */
frb.localizeAmountOptions = function(source, currency, country, language, useSymbols) {
var amountOptions = frb.pickAmounts(source, currency, country);
$('#frb-form input[name="amount"]').each(function(index) { var $input = $(this); var $label = $input.siblings('label');
var i = $input.attr('id').replace('frb-amt-ps', ); var amount = amountOptions[i-1]; // because IDs start from 1
if ( amount ) { $input.val( amount ); if ( useSymbols ) { $label.text( frb.formatCurrency( currency, amount, language) ); } else { $label.text( frb.formatCurrency( undefined, amount, language) ); } } });
};
/**
* Make an element into a link * * @param {string} selector CSS selector for elements to convert to a link * @param {string} language Code of language (could be es-419 or pt-br) * @param {string} baseUrl URL of link (function will add language parameter) */
frb.makeLink = function( selector, language, baseUrl ) { var url = baseUrl + '&language=' + language; $( selector ).each( function() { var $link = $( '<a></a>' ); $link.html( $( this ).html() ); $link.attr( { href: url, target: '_blank' } ); $( this ).replaceWith( $link ); }); };
/**
* Get the number of banners seen from localStorage * @return {number} Number of banners seen */
frb.getSeenCount = function () {
// Force with URL parameter 'impression' if ( typeof URLSearchParams === 'function' ) { // not available in old browsers var urlParams = new URLSearchParams( window.___location.search ); if ( urlParams.has( 'impression' ) ) { return urlParams.get( 'impression' ); } }
try { if ( localStorage ) { var identifier = mw.centralNotice.internal.state.campaign.mixins.impressionDiet.cookieName, lsName = 'CentralNoticeKV|global|impression_diet_' + identifier, diet = JSON.parse( localStorage.getItem( lsName ) ); if ( diet ) { return diet.val.seenCount; } } } catch ( ex ) { // do nothing - localStorage is configured not to let us read it, or mixin not set return; } };
/**
* Helper function to do text replacements and wrap them in correct class * * @param {RegExp} regex Regular expression to replace * @param {string} replacement String to replace it with */
frb.textReplace = function( regex, replacement ) { $( '.frb' ).each( function( index ) { var newHtml = $( this ).html(); newHtml = newHtml.replace( regex, '' + replacement + '' ); $( this ).html( newHtml ); }); };
/**
* Replace elements with preset ask string amounts * * e.g. class="frb-replace-amt-ps4" will be replaced with amount #4, currently $25 in the US * * @param {string} currency - currency code e.g. 'USD' * @param {string} country - country code e.g. 'FR' * @param {string} language - language code e.g. 'en' For symbol formatting */
frb.replaceCustomAmounts = function( currency, country, language ) { var amountOptions = frb.pickAmounts( frb.amounts.options7, currency, country );
// Old style element replacements $( '.frb [class^="frb-replace-amt-ps"]' ).each( function() { var i = $( this ).attr( 'class' ).replace( 'frb-replace-amt-ps', ), amount = amountOptions[ i - 1 ], formattedAmount = frb.formatCurrency( currency, amount, language ); $( this ).html( '<frb-amt>' + formattedAmount + '</frb-amt>' ); });
// Text replacements e.g. %amount-4% // There is probably a more efficient way to do this, but it's at least fairly simple for (var i = 0; i < amountOptions.length; i++) { var amount = amountOptions[i], formattedAmount, regex = new RegExp( '%amount-' + (i+1) + '%', 'gi' ); if ( frb.textAmountIsoCountries.includes( country ) ) { formattedAmount = frb.formatCurrency( undefined, amount, language ) + ' ' + currency; } else { formattedAmount = frb.formatCurrency( currency, amount, language ); } frb.textReplace( regex, formattedAmount ); } };
/**
* Get today's date like "December 3" - English only for now * * @return {string} Today's date as a string */
frb.getDateString = function() { var date = new Date(), locale = mw.centralNotice.data.uselang + '-' + mw.centralNotice.data.country; return date.toLocaleString( locale, { day: 'numeric', month: 'long' } ); };
frb.noRecurringCountries = ['AR', 'IN'];
/* These countries use potentially ambiguous $ sign. Use ISO code instead in text (but still $ for buttons) */ frb.textAmountIsoCountries = ['AR', 'CL', 'CO', 'MX'];
$(function() {
if ( mw.centralNotice.adminUi ) { // T262693 return; }
var language = mw.centralNotice.data.uselang; var variantLanguage; // for pt-br and es-419, note we can only use these for certain links var country = mw.centralNotice.data.country; var currency = frb.getCurrency(country);
if ( language === 'pt' && country === 'BR' ) { variantLanguage = 'pt-br'; } else if ( language === 'es' && ['AR', 'CL', 'CO', 'PE', 'MX', 'UY'].indexOf( country ) !== -1 ) { variantLanguage = 'es-419'; } else { variantLanguage = language; }
// Payment methods frb.localizeMethods(country); frb.checkMethodOutages(country);
// Preset amounts frb.replaceCustomAmounts( currency, country, language );
// Basic replacements $('.frb-replace-currencysymbol').text( frb.formatCurrency( currency, , language ).replace(' ', ) ); $('.frb-replace-currencycode').text( currency );
// Country name var countryName; if ( frb.countryNames[language] ) { countryName = frb.countryNames[language][country] || frb.countryNames.en[country]; } else { countryName = frb.countryNames.en[country]; } $( '.frb-replace-countryname' ).text( countryName ); frb.textReplace( /%country%/gi, countryName );
// "in COUNTRY" or equivalent var inCountryName; if ( frb.inCountryNames[language] ) { inCountryName = frb.inCountryNames[language][country] || frb.inCountryNames.en[country]; } else { inCountryName = frb.inCountryNames.en[country]; } $( '.frb-replace-incountryname' ).text( inCountryName ); frb.textReplace( /%in-country%/gi, inCountryName );
// Day of week // TODO: Replace these with date.toLocaleString so we can drop frb.dayNames? // Might still need some ways to deal with "this" and capitalization var now = new Date(); var dayNumber = now.getDay(); var capitalizeText = function( text ) { // Capitalize first letter, for use at start of sentence return text.charAt(0).toUpperCase() + text.slice(1); };
if ( $('.frb-replace-dayofweek, .frb-replace-dayofweek-capitalize').length > 0 ) { if ( frb.dayNames[language] ) { $('.frb-replace-dayofweek').text( frb.dayNames[language][dayNumber] ); $('.frb-replace-dayofweek-capitalize').text( capitalizeText( frb.dayNames[language][dayNumber] ) ); } else { console.log('Warning: banner should contain a day of the week, but no translations found.'); } }
if ( $('.frb-replace-dayofweek-this, .frb-replace-dayofweek-this-capitalize').length > 0 ) { if ( frb.dayNamesThis[language] ) { $('.frb-replace-dayofweek-this').text( frb.dayNamesThis[language][dayNumber] ); $('.frb-replace-dayofweek-this-capitalize').text( capitalizeText( frb.dayNamesThis[language][dayNumber] ) ); } else { console.log('Warning: banner should contain "this DAY", but no translations found.'); } }
// Simple %weekday% text replacement try { if ( frb.dayNames[language] ) { frb.textReplace( /%weekday%/gi, frb.dayNames[language][dayNumber] ); } else { frb.textReplace( /%weekday%/gi, frb.dayNames['en'][dayNumber] ); } } catch ( error ) { console.error( error ); }
// Replace %date% with today's date e.g. "December 3" try { frb.textReplace( /%date%/gi, frb.getDateString() ); } catch ( error ) { console.log( error ); }
// Capitalize $('.frb-capitalize').text(function( index, text ) { return text.charAt(0).toUpperCase() + text.slice(1); });
// Replace %average%, %minimum% and %amount% var average = frb.pickAmounts( frb.amounts.averages, currency, country ), ifEveryone = frb.pickAmounts( frb.amounts.ifEveryone, currency, country ), avgString, ifString;
if ( frb.textAmountIsoCountries.indexOf(country) !== -1 ) { avgString = frb.formatCurrency( undefined, average, language ) + ' ' + currency; ifString = frb.formatCurrency( undefined, ifEveryone, language ) + ' ' + currency; } else { avgString = frb.formatCurrency( currency, average, language ).replace( /\.$/, ); // strip any period from end for use in running text ifString = frb.formatCurrency( currency, ifEveryone, language ).replace( /\.$/, ); } frb.textReplace( /%average%/gi, avgString ); frb.textReplace( /%minimum%/gi, ifString ); frb.textReplace( /%amount%/gi, ifString );
/** * Call a function on every text node contained by a root node. * * Used so we can do text replacements without accidentally clobbering html and scripts * * @param {Node} rootNode The Node object whose descendants will be recursed through * @param {Function} callback Callback function that receives a Node as its only argument */ function eachTextNode( rootNode, callback ) { for ( var node = rootNode.firstChild; node !== null; node = node.nextSibling ) { if ( node.nodeType === Node.TEXT_NODE ) { callback( node ); } else if ( node.nodeType === Node.ELEMENT_NODE ) { eachTextNode( node, callback ); } } }
// French spacing: replace space before punctuation with if ( language === 'fr' ) { var bannerRootElements = document.getElementsByClassName( 'frb' ); for ( var i = 0; i < bannerRootElements.length; i++ ) { eachTextNode( bannerRootElements[i], function( node ) { node.textContent = node.textContent.replace( / ([!?;:%])/g, '\u00a0$1' ); }); } }
// Links (in smallprint) TODO: merge with frb.makeLink() $('.frb-localize-links a').each(function() { // Add parameters for LandingCheck var url = new URL( $(this).attr('href') ); url.searchParams.set( 'country', country ); url.searchParams.set( 'language', variantLanguage ); // is this needed? url.searchParams.set( 'uselang', variantLanguage ); url.searchParams.set( 'wmf_medium', 'sitenotice' ); url.searchParams.set( 'wmf_campaign', mw.centralNotice.data.campaign || 'test' ); url.searchParams.set( 'wmf_source', mw.centralNotice.data.banner ); $(this).attr('href', url.toString()); $(this).attr('target', '_blank'); // Make links open in new tab });
// Add links frb.makeLink( '.frb-link-privacy', variantLanguage, 'https://foundation.wikimedia.org/wiki/Special:LandingCheck?basic=true&landing_page=Donor_privacy_policy' ); frb.makeLink( '.frb-link-tax', variantLanguage, 'https://donate.wikimedia.org/wiki/Special:LandingCheck?basic=true&landing_page=Tax_deductibility' ); frb.makeLink( '.frb-link-cancel', variantLanguage, 'https://donate.wikimedia.org/wiki/Special:LandingCheck?basic=true&landing_page=Cancel_or_change_recurring_giving' );
// Legal text variants if (country === 'US') { $('.frb-legal-US').show(); $('.frb-legal-nonUS, .frb-legal-NL').hide(); } else if (country === 'NL') { $('.frb-legal-NL').show(); $('.frb-legal-US, .frb-legal-nonUS').hide(); } else { $('.frb-legal-nonUS').show(); $('.frb-legal-US, .frb-legal-NL').hide(); }
// Quick hack for American/British/Commonwealth English differences if ( country === 'US' ) { $('.frb-lang-enUS').show(); $('.frb-lang-en5C').hide(); } else { $('.frb-lang-enUS').hide(); $('.frb-lang-en5C').show(); }
// Add this so they get white-space: nowrap from CSS $('.frb-ptf-fee, .frb-ptf-total, .frb-upsell-ask').addClass('frb-replaced');
// Where Remind Me Later should be shown var rmlCountries = ['US', 'CA', 'GB', 'IE', 'AU', 'NZ', 'NL', 'IN', 'FR', 'ES', 'JP', 'BR', 'CL', 'CO', 'MX', 'PE', 'UY']; var rmlLanguages = ['en', 'nl', 'ja', 'it', 'sv', 'pt', 'cs', 'es', 'ca', 'fr', 'aa']; var rmlEnabled = !frb.isEndowment && rmlCountries.indexOf(country) !== -1 && rmlLanguages.indexOf(language) !== -1;
if ( rmlEnabled ) { $('.frb').addClass('frb-rml-enabled'); } else { $('.frb').addClass('frb-rml-disabled'); }
});
/* == end of MediaWiki:FundraisingBanners/LocalizeJS-2022.js == */ /* eslint-env es6 */ var frb = frb || {};
/* Based on github:braintree/braintree-web/src/venmo/shared/supports-venmo.js */ frb.isVenmoSupported = function(options) {
var options = options || { allowNewBrowserTab: false, allowWebviews: true, allowDesktop: true, allowDesktopWebLogin: true }; var ua = window.navigator.userAgent;
var merchantAllowsReturningToNewBrowserTab, merchantAllowsWebviews, merchantAllowsDesktopBrowsers; var isMobileDevice = isAndroid() || isIos(); var isAndroidChrome = isAndroid() && isChrome(); var isMobileDeviceThatSupportsReturnToSameTab = isIosSafari() || isAndroidChrome; var isKnownUnsupportedMobileBrowser = isIosChrome() || isFacebookOwnedBrowserOnAndroid() || isSamsung();
options = options || {}; // NEXT_MAJOR_VERSION allowDesktop will default to true, but can be opted out merchantAllowsDesktopBrowsers = (options.allowDesktopWebLogin || options.allowDesktop) === true; merchantAllowsReturningToNewBrowserTab = options.hasOwnProperty( "allowNewBrowserTab" ) ? options.allowNewBrowserTab : true; // NEXT_MAJOR_VERSION webviews are not supported, except for the case where // the merchant themselves is presenting venmo in a webview using the deep // link url to get back to their app. For the next major version, we should // just not have this option and instead require the merchant to determine // if the venmo button should be displayed when presenting it in the // merchant's app via a webview. merchantAllowsWebviews = options.hasOwnProperty("allowWebviews") ? options.allowWebviews : true;
if (isKnownUnsupportedMobileBrowser) { return false; }
if ( !merchantAllowsWebviews && (isAndroidWebview() || isIosWebview()) ) { return false; }
if (!isMobileDevice) { return merchantAllowsDesktopBrowsers; }
if (!merchantAllowsReturningToNewBrowserTab) { return isMobileDeviceThatSupportsReturnToSameTab; }
return isMobileDevice;
/* -- functions mostly from github:braintree/browser-detection library -- */
function isAndroid() { return /Android/i.test(ua); }
function isIos(checkIpadOS = true) { const iOsTest = /iPhone|iPod|iPad/i.test(ua); return checkIpadOS ? iOsTest || isIpadOS() : iOsTest; }
function isIpadOS() { // "ontouchend" is used to determine if a browser is on an iPad, otherwise // user-agents for iPadOS behave/identify as a desktop browser return /Mac|iPad/i.test(ua) && "ontouchend" in window.document; }
function isEdge() { return ua.indexOf("Edge/") !== -1 || ua.indexOf("Edg/") !== -1; }
function isSamsung() { return /SamsungBrowser/i.test(ua); }
function isDuckDuckGo() { return ua.indexOf("DuckDuckGo/") !== -1; }
function isOpera() { return ( ua.indexOf("OPR/") !== -1 || ua.indexOf("Opera/") !== -1 || ua.indexOf("OPT/") !== -1 ); }
function isSilk() { return ua.indexOf("Silk/") !== -1; }
function isChrome() { return ( (ua.indexOf("Chrome") !== -1 || ua.indexOf("CriOS") !== -1) && !isEdge() && !isSamsung() && !isDuckDuckGo() && !isOpera() && !isSilk() ); }
function isIosFirefox() { return /FxiOS/i.test(ua); }
function isWebkit() { const webkitRegexp = /webkit/i; return webkitRegexp.test(ua); }
function isIosChrome() { return ua.indexOf("CriOS") > -1; }
function isFacebook() { return ua.indexOf("FBAN") > -1; }
function isIosSafari() { return ( isIos() && isWebkit() && !isIosChrome() && !isIosFirefox() && !isFacebook() ); }
function isFacebookOwnedBrowserOnAndroid() { var e = ua.toLowerCase(); return -1 < e.indexOf("huawei") && -1 < e.indexOf("fban") || isAndroid() && (-1 < e.indexOf("fb_iab") || -1 < e.indexOf("instagram")); }
function isSamsungBrowser() { return /SamsungBrowser/i.test(ua); }
function isAndroidWebview() { return isAndroid() && -1 < ua.toLowerCase().indexOf("wv"); }
function isGoogleSearchApp() { return /\bGSA\b/.test(ua); }
function isIosGoogleSearchApp() { return isIos() && isGoogleSearchApp(); }
function isIosWebview() { if (isIos()) { // The Google Search iOS app is technically a webview and doesn't support popups. if (isIosGoogleSearchApp()) { return true; } // Historically, a webview could be identified by the presence of AppleWebKit and _no_ presence of Safari after. return /.+AppleWebKit(?!.*Safari)/i.test(ua); } return false; }
};
frb.HIDE_DURATION_CLOSE = 604800; // 1 week frb.HIDE_DURATION_RML = 604800; // 1 week frb.HIDE_DURATION_CLOSENAG = 86400; // 1 day frb.HIDE_DURATION_ALREADYDONATED = 604800; // 1 week
frb.storedOptions = {};
frb.animationDuration = frb.reduceMotion ? 0 : 400; // slides and scrolls frb.fadeDuration = frb.reduceMotion ? 0 : 600; // transitions between steps
/* Hide banner and nag, and remove related event handlers */ frb.hide = function() {
$('#centralNotice, .frb').hide(); $(window).off('.frb'); clearInterval(frb.updatingTimeInterval);
};
frb.insertInlineBanner = function() {
// Place frb-inline in article, before first paragraph or at top var $inlineBanner = $('#frb-inline'); var $firstPara = $('.mw-parser-output > div > p:not(.mw-empty-elt)').first();
if ( $firstPara.length > 0 && !mw.config.get('wgIsMainPage') ) { $firstPara.before( $inlineBanner ); } else { $('#mw-content-text').prepend( $inlineBanner ); }
$inlineBanner.show();
};
frb.rml = {
post: function() { /* Create the iframe for the form and use it as the form's target */ var frameName = 'remindFrame'; var $form = $('#frb-rml-form'); if ( $("iframe[name=" + frameName + "]").length === 0 ) { var $iframe = $('<iframe style="display: none;" name="' + frameName + '"></iframe>'); $form.attr('target', $iframe.attr('name')); $form.after($iframe); } $form[0].submit(); },
getCurrentDate: function() { /* Get current date in correct format for Silverpop */ var today = new Date(); var dd = today.getDate(); var mm = today.getMonth()+1; // January is 0! var yyyy = today.getFullYear();
if( dd < 10 ) { dd = '0' + dd; } if( mm < 10 ) { mm = '0' + mm; }
return mm+'/'+dd+'/'+yyyy; },
init: function() { /* Prep the reminder form */
var form = document.getElementById('frb-rml-form'), rmlDialog = document.getElementById('frb-dialog-rml');
form.rml_country.value = mw.centralNotice.data.country; form.rml_language.value = mw.centralNotice.data.uselang; form.rml_submitDate.value = frb.rml.getCurrentDate(); form.rml_segment.value = Math.floor((Math.random() * 100) + 1);
$('#frb-inline .frb-rml-link').on( 'click', function(e) { rmlDialog.showModal(); form.rml_source.value = mw.centralNotice.data.banner; return false; });
$('#frb-nag .frb-rml-link').on( 'click', function(e) { rmlDialog.showModal(); form.rml_source.value = mw.centralNotice.data.banner + '_nag'; return false; });
$('#frb-dialog-rml .frb-dialog-close').on('click', function (e) { rmlDialog.close(); }); rmlDialog.addEventListener( 'click', frb.closeOnClickOutside );
$('#frb-rml-submit').click(function() { if ( mw.util.validateEmail( form.Email.value ) ) { frb.rml.post(); $('#frb-rml-form').hide(); $('.frb-rml-ty').show(); window.setTimeout( function() { rmlDialog.close(); frb.hide(); }, 2500); frb.altSetHideCookie( 'close', frb.HIDE_DURATION_RML ); return false; } else { $('#frb-rml-email').addClass('frb-haserror').focus(); $('.frb-error-invalidemail').show(); return false; } }); }
};
frb.initNag = function() {
/* --- Code for sticky "nag" banner --- */ var nagHoverTimeout;
$(window).scroll(function() { var nagRevealPosition = $('#frb-inline').offset().top + $('#frb-inline').outerHeight();
if ( $(window).scrollTop() <= nagRevealPosition ) { $('#frb-nag').finish(); $('#frb-nag').hide(); } else { setTimeout(function(){ if ( $(window).scrollTop() > nagRevealPosition ) { $('#frb-nag').slideDown( frb.animationDuration ); } }, 1500); } });
$('.frb-nag-close').click(function(e) { $('#centralNotice').hide(); // Hide nag (but not inline banner) frb.altSetHideCookie( 'close', frb.HIDE_DURATION_CLOSENAG ); clearInterval(frb.updatingTimeInterval); e.stopPropagation(); });
};
/* Helper function to close dialog if clicked outside */ frb.closeOnClickOutside = function(e) {
if ( e.target.tagName !== 'DIALOG' ) { return false; } let rect = e.target.getBoundingClientRect(); if ( e.clientY < rect.top || e.clientY > rect.bottom || e.clientX < rect.left || e.clientX > rect.right ) { e.target.close(); }
}
$(function() {
if ( mw.centralNotice.adminUi || !frb.supportedBrowser ) { // T262693 return; }
frb.toggleMonthly = function( monthly ) { if ( monthly.type === 'checkbox' ) { monthly = monthly.checked; } if ( monthly ) { $('#frb-frequency-monthly').prop('checked', true); $('#frb-monthly-checkbox').prop('checked', true); $('.no-monthly input').attr('disabled', true); $('#frb-form').addClass('form-monthly'); if ( $('.form-monthly .no-monthly input[type=radio]').is(':checked') ) { $('.form-monthly .no-monthly input[type=radio]').removeAttr('checked'); frb.setMethod({}); } } else { $('#frb-frequency-onetime').prop('checked', true); $('#frb-monthly-checkbox').prop('checked', false); $('.no-monthly input').attr('disabled', false); $('#frb-form').removeClass('form-monthly'); } };
var language = mw.centralNotice.data.uselang; var country = mw.centralNotice.data.country; var currency = frb.getCurrency(country); var validAmount, validMethod, validStayInTouch; if ( !frb.optinRequired ) { validStayInTouch = 1; } var form = document.getElementById('frb-form');
frb.extraData = {};
mw.loader.using(['mediawiki.util']).then(function() { frb.rml.init(); });
frb.initAmountOptions(); frb.localizeAmountOptions(frb.amounts.options7, currency, country, language, true); frb.localizeErrors();
// Override frb.updateFeeDisplay = function() { var currency = frb.getCurrency(mw.centralNotice.data.country), language = mw.centralNotice.data.uselang, amount, feeAmount, totalAmount;
amount = frb.getAmount(); feeAmount = frb.calculateFee(amount); if ( $('#frb-ptf-checkbox').prop('checked') ) { totalAmount = amount + feeAmount; } else { totalAmount = amount; }
var feeAmountFormatted = frb.formatCurrency(currency, feeAmount, language); $('.frb-ptf-fee').text(feeAmountFormatted);
var totalAmountFormatted = frb.formatCurrency(currency, totalAmount, language); $('.frb-ptf-total').text(totalAmountFormatted);
if ( validAmount && validMethod ) { $('.frb-ptf').slideDown( frb.reduceMotion ? 0 : 400 ); } };
frb.activateCTA = function () { if (validAmount && validMethod && validStayInTouch) { $('.frb-form .frb-submit').addClass('active'); $('.frb-submit-txt-continue').hide(); $('.frb-submit-txt-donate').show(); } else { $('.frb-form .frb-submit').removeClass('active'); } };
$('.frb-amounts').on('input change', function() { frb.validateAmount(); validAmount = 1; frb.updateFeeDisplay(); frb.activateCTA(); });
frb.setMethod = function (options, frequency) { frb.storedOptions = options || { method: 'cc' }; // Default to credit card
if( frequency === 'no-monthly' ) { $('#frb-frequency-monthly').attr('disabled', true); $('#frb-form').addClass('form-monthly-disabled'); } else { $('#frb-frequency-monthly').attr('disabled', false); $('#frb-form').removeClass('form-monthly-disabled'); } validMethod = 1; frb.updateFeeDisplay(); frb.activateCTA(); };
// Opt-in requred for certain countries, defined in CoreJS if ( frb.optinRequired ) { $('.frb-optin').show(); }
// Opt-in interaction $('.frb-optin').on('change', function() { $('.frb-optin').removeClass('frb-haserror'); validStayInTouch = 1; frb.activateCTA(); $('.frb-error-optin').hide(); if ( $('#frb-optin-no').is(':checked') ) { $('.frb-optin-no-prompt').removeClass('is-positive'); if ( !$('.frb-optin-no-prompt').is(':visible') ) { $('.frb-optin-no-prompt').slideDown( frb.animationDuration ); } } else { $('.frb-optin-no-prompt').addClass('is-positive'); } });
$('.frb-inline-close').on('click', function(e) { frb.hide(); frb.altSetHideCookie( 'close', frb.HIDE_DURATION_CLOSE ); frb.showDonateLinkTooltip( '{{{FR2015_translations,sidebar-donate-callout}}}' ); return false; });
/* -- UPSELL -- */ frb.updateUpsellAsk = function(isOtherAmountStep) { var amount, feeAmount, upsellAmount, list = frb.amounts.monthlySuggest[currency];
if ( list === undefined ) { console.log('No monthlySuggest amounts found for ' + currency); return; }
// If user is on third step (write a different amount) then get monthly amount if not, the the first form amount if (isOtherAmountStep !== undefined) { amount = frb.getMonthlyAmount(); } else { amount = frb.getAmount(form); }
// If PTF is checked when we need to calculate the fee for that amount if ( $('#frb-ptf-checkbox').prop('checked') ) { amount = amount + frb.calculateFee(amount); }
for (var i = list.length - 1; i >= 0; i--) { if ( amount <= list[i][0] ) { upsellAmount = list[i][1]; } }
// If user is in the upsell (second step) then the form.otherMonthlyAmount.value will be updated with the upsellAmount calculated if (isOtherAmountStep === undefined) { form.otherMonthlyAmount.value = upsellAmount; }
// A formatted value will be returned var upsellAmountFormatted = frb.formatCurrency(currency, upsellAmount, language);
// The value of the amount will be updated only if the user is in the upsell (second step) if (isOtherAmountStep === undefined) { $('.frb-upsell-ask').text(upsellAmountFormatted); } };
/** * Should we show pre-payment monthly convert? * * Only if: initial selection is one-time, suggested amount is not 0 (meaning skip), * payment method supports monthly, and payment method does not have post-payments monthly convert * * @returns boolean */ frb.shouldShowMonthlyConvert = function() { let postPaymentMethods = [ 'cc', 'apple', 'google', 'dd' ]; // dd = ACH if ( frb.getRecurring( document.getElementById( 'frb-form' ) ) || !frb.shouldShowRecurring( frb.storedOptions, mw.centralNotice.data.country ) || form.otherMonthlyAmount.value == 0 || postPaymentMethods.includes( frb.storedOptions.method ) ) { return false; } else { return true; } }
$('#frb-btn-first-submit').on('click', function (e) { e.preventDefault();
if ( frb.validateForm( frb.storedOptions ) ) { frb.updateUpsellAsk();
if ( frb.shouldShowMonthlyConvert() ) { $('.frb-step-2').fadeOut( frb.fadeDuration, function () { $('.frb-step-upsell').fadeIn( frb.fadeDuration, function() { $('html, body').animate( { scrollTop: $('.frb-upsell-cta').offset().top - 10 }, frb.animationDuration ); }); }); } else { frb.submitForm( frb.storedOptions ); } } else { frb.extraData.validateError = 1; } });
// Go back to step 2 from upsell $('.frb-step-upsell .frb-back').on('click', function (e) { $('.frb-step-upsell').hide(); $('.frb-step-2').show(); return false; });
// Go back to upsell from diff-amt $('.frb-step-monthly-diff-amt .frb-back').on('click', function (e) { form.otherMonthlyAmount.value = ; frb.updateUpsellAsk(); validAmount = 1; frb.activateCTA(); frb.toggleMonthly(false); $('.frb-step-monthly-diff-amt').hide(); $('.frb-step-upsell').show(); return false; });
// Donate monthly other amount $('.frb-monthly-diff-amt-link').on('click', function (e) { form.otherMonthlyAmount.value = ; validAmount = 0; frb.activateCTA(); frb.toggleMonthly(true); $('.frb-step-upsell').hide(); $('.frb-step-monthly-diff-amt').show(); return false; });
// Validate monthly other amount $('#frb-amt-monthly-other-input').on('input change', function (e) { if (frb.validateMonthlyAmount()) { validAmount = 1; frb.updateUpsellAsk(true); } else { validAmount = 0; } frb.activateCTA(); });
// Submit/"Donate now" buttons $('#frb-monthly-donate-yes').on('click', function (e) { frb.submitMonthly(); return false; });
$('#frb-monthly-donate-no').on('click', function (e) { frb.submitForm(frb.storedOptions); return false; });
$('#frb-donate-monthly-other').on('click', function (e) { if (frb.validateMonthlyAmount()) { frb.submitMonthly(); } return false; });
frb.getMonthlyAmount = function () { var form = document.getElementById('frb-form'); var amount = null;
// Check the "monthly other" amount box if (form.otherMonthlyAmount.value !== ) { var otherMonthlyAmount = form.otherMonthlyAmount.value; otherMonthlyAmount = otherMonthlyAmount.replace(/[,.](\d)$/, ':$10'); otherMonthlyAmount = otherMonthlyAmount.replace(/[,.](\d)(\d)$/, ':$1$2'); otherMonthlyAmount = otherMonthlyAmount.replace(/[$£€¥,.]/g, ); otherMonthlyAmount = otherMonthlyAmount.replace(/:/, '.'); amount = otherMonthlyAmount; }
amount = parseFloat(amount);
if (isNaN(amount)) { return 0; } else { var totalMonthlyAmountFormatted = frb.formatCurrency(currency, amount, language); $('.frb-monthly-total').text(totalMonthlyAmountFormatted);
return amount; } };
frb.validateMonthlyAmount = function () {
var amount = frb.getMonthlyAmount(); var currency = frb.getCurrency( mw.centralNotice.data.country ); var minAmount = frb.amounts.minimums[ currency ];
if ( amount === null || isNaN(amount) || amount <= 0 || amount < minAmount ) { $('.frb-error-bigamount').hide(); $('.frb-error-smallamount').show(); return false; } else if ( amount > frb.maxUSD * minAmount ) { $('.frb-error-bigamount').show(); return false; } else { $('.frb-error-smallamount, .frb-error-bigamount').hide(); return true; } };
frb.submitMonthly = function() { frb.extraData.monthlyUpsell = 1; frb.extraData.originalAmt = frb.getAmount().toString();
frb.toggleMonthly(true); document.getElementById('frb-input-other').checked = true; document.getElementById('frb-ptf-checkbox').checked = false; form.otherAmount.value = form.otherMonthlyAmount.value; frb.submitForm(frb.storedOptions); }
// Focus for Other field $('.frb-button--other').on('click keypress', function(e) { if ( e.which === 13 || e.type === 'click' ) { document.getElementById('frb-input-other').checked = true; frb.updateFeeDisplay(); $('.frb-other-input').focus(); e.stopPropagation(); } });
/* Other amount field focus styles */ $('.frb-other-input') .focus(function() { $('.frb-button--other').addClass('frb-button--is-focused'); }) .blur(function() { $('.frb-button--other').removeClass('frb-button--is-focused'); });
// Activate #input_amount_other radio when tabbing into #frb-amt-other-input // Add focus class to parent $('#frb-amt-other-input') .blur(function() { $(this).closest('.frb-amt-other').removeClass('is-focused'); }) .focus(function() { document.getElementById('frb-input-other').checked = true; frb.updateFeeDisplay(); $(this).closest('.frb-amt-other').addClass('is-focused'); });
/* I already donated */ var iadDialog = document.getElementById('frb-dialog-iad');
$('.frb-iad-link').on('click', function(e) { iadDialog.showModal(); });
$('#frb-dialog-iad .frb-dialog-close').on('click', function(e) { iadDialog.close(); if (e.target.name == 'frb-iad-hide-button') { frb.hide(); frb.altSetHideCookie( 'donate close', frb.HIDE_DURATION_ALREADYDONATED ); e.target.blur(); } $('.frb-iad-link').focus(); }); iadDialog.addEventListener( 'click', frb.closeOnClickOutside );
$(document).on("click", "#donate-minimum", function(e) { e.preventDefault(); $('#frb-amt-ps1').click(); $('.frb-step-1').hide(); $('.frb-step-2').fadeIn( frb.fadeDuration ); });
$(document).on("click", "#donate-custom", function(e) { e.preventDefault(); $('.frb-step-1').hide(); $('.frb-step-2').fadeIn( frb.fadeDuration ); });
$(document).on("click", "#frb-nag .frb-nag-action", function(e) { e.preventDefault(); $('.frb-cta-first, .frb-step-upsell, .frb-step-monthly-diff-amt').hide(); $('#frb-amt-ps1').click(); $('html, body').animate( { scrollTop: $('#frb-inline').offset().top }, frb.animationDuration ); $('.frb-step-1, .frb-step-2').show(); $('#frb-nag').slideToggle( frb.animationDuration ); frb.extraData.clickedNag = 1; });
// Text resizing - increase font size until just before it overflows const isOverflown = ({ clientHeight, scrollHeight }) => scrollHeight > clientHeight; const resizeText = ({ element, elements, minSize = 12, maxSize = 16, step = 1, unit = 'px' }) => { (elements || [element]).forEach(el => { let i = minSize; let overflow = false; const parent = el.parentNode;
while (!overflow && i < maxSize) { el.style.fontSize = `${i}${unit}`; overflow = isOverflown(parent); if (!overflow) { i += step; } } // revert to last state where no overflow happened el.style.fontSize = `${i - step}${unit}` }) };
var throttleResize; window.onresize = function(){ clearTimeout(throttleResize); throttleResize = setTimeout(resizeText({ elements: document.querySelectorAll('.frb-inline-message-text'), step: 0.5 }), 100); };
frb.getTimeString = function() { var date = new Date(), locale = mw.centralNotice.data.uselang + '-' + mw.centralNotice.data.country; return date.toLocaleTimeString( locale, { hour: 'numeric', minute: '2-digit' } ); };
$('.frb-updating-time').text( frb.getTimeString ); frb.updatingTimeInterval = setInterval(function() { $('.frb-updating-time').text( frb.getTimeString ); }, 5000);
if ( frb.shouldShowBanner() ) { frb.insertInlineBanner(); resizeText({ elements: document.querySelectorAll('.frb-inline-message-text'), step: 0.5 }); frb.initNag(); }
}); </script>