vue-recaptcha
Version:
ReCAPTCHA vue component
194 lines (172 loc) • 4.29 kB
JavaScript
function _extends() {
_extends = Object.assign || function (target) {
for (var i = 1; i < arguments.length; i++) {
var source = arguments[i];
for (var key in source) {
if (Object.prototype.hasOwnProperty.call(source, key)) {
target[key] = source[key];
}
}
}
return target;
};
return _extends.apply(this, arguments);
}
var defer = function defer() {
var state = false; // Resolved or not
var callbacks = [];
var resolve = function resolve(val) {
if (state) {
return;
}
state = true;
for (var i = 0, len = callbacks.length; i < len; i++) {
callbacks[i](val);
}
};
var then = function then(cb) {
if (!state) {
callbacks.push(cb);
return;
}
cb();
};
var deferred = {
resolved: function resolved() {
return state;
},
resolve: resolve,
promise: {
then: then
}
};
return deferred;
};
function createRecaptcha() {
var deferred = defer();
return {
notify: function notify() {
deferred.resolve();
},
wait: function wait() {
return deferred.promise;
},
render: function render(ele, options, cb) {
this.wait().then(function () {
cb(window.grecaptcha.render(ele, options));
});
},
reset: function reset(widgetId) {
if (typeof widgetId === 'undefined') {
return;
}
this.assertLoaded();
this.wait().then(function () {
return window.grecaptcha.reset(widgetId);
});
},
execute: function execute(widgetId) {
if (typeof widgetId === 'undefined') {
return;
}
this.assertLoaded();
this.wait().then(function () {
return window.grecaptcha.execute(widgetId);
});
},
checkRecaptchaLoad: function checkRecaptchaLoad() {
if (window.hasOwnProperty('grecaptcha') && window.grecaptcha.hasOwnProperty('render')) {
this.notify();
}
},
assertLoaded: function assertLoaded() {
if (!deferred.resolved()) {
throw new Error('ReCAPTCHA has not been loaded');
}
}
};
}
var recaptcha = createRecaptcha();
if (typeof window !== 'undefined') {
window.vueRecaptchaApiLoaded = recaptcha.notify;
}
var VueRecaptcha = {
name: 'VueRecaptcha',
props: {
sitekey: {
type: String,
required: true
},
theme: {
type: String
},
badge: {
type: String
},
type: {
type: String
},
size: {
type: String
},
tabindex: {
type: String
},
loadRecaptchaScript: {
type: Boolean,
"default": false
},
recaptchaScriptId: {
type: String,
"default": '__RECAPTCHA_SCRIPT'
},
recaptchaHost: {
type: String,
"default": 'www.google.com'
}
},
beforeMount: function beforeMount() {
if (this.loadRecaptchaScript) {
if (!document.getElementById(this.recaptchaScriptId)) {
// Note: vueRecaptchaApiLoaded load callback name is per the latest documentation
var script = document.createElement('script');
script.id = this.recaptchaScriptId;
script.src = "https://" + this.recaptchaHost + "/recaptcha/api.js?onload=vueRecaptchaApiLoaded&render=explicit";
script.async = true;
script.defer = true;
document.head.appendChild(script);
}
}
},
mounted: function mounted() {
var _this = this;
recaptcha.checkRecaptchaLoad();
var opts = _extends({}, this.$props, {
callback: this.emitVerify,
'expired-callback': this.emitExpired
});
var container = this.$slots["default"] ? this.$el.children[0] : this.$el;
recaptcha.render(container, opts, function (id) {
_this.$widgetId = id;
_this.$emit('render', id);
});
},
methods: {
reset: function reset() {
recaptcha.reset(this.$widgetId);
},
execute: function execute() {
recaptcha.execute(this.$widgetId);
},
emitVerify: function emitVerify(response) {
this.$emit('verify', response);
},
emitExpired: function emitExpired() {
this.$emit('expired');
}
},
render: function render(h) {
return h('div', {}, this.$slots["default"]);
}
};
export default VueRecaptcha;