diff --git a/.editorconfig b/.editorconfig
new file mode 100644
index 0000000..9df53e0
--- /dev/null
+++ b/.editorconfig
@@ -0,0 +1,18 @@
+# EditorConfig is awesome: http://EditorConfig.org
+
+# top-most EditorConfig file
+root = true
+
+# Unix-style newlines with a newline ending every file
+[*]
+end_of_line = lf
+insert_final_newline = true
+
+[*.js]
+charset = utf-8
+indent_style = space
+indent_size = 2
+
+[{package.json,.travis.yml}]
+indent_style = space
+indent_size = 2
diff --git a/.eslintrc b/.eslintrc
index 77ffa2d..73f0d5d 100644
--- a/.eslintrc
+++ b/.eslintrc
@@ -15,6 +15,7 @@
"comma-dangle": [2, "always-multiline"],
"comma-spacing": 1,
"key-spacing": 0,
+ "indent": ["error", 2],
"no-mixed-spaces-and-tabs": 2,
"no-multiple-empty-lines": [1, { "max": 1}],
"no-underscore-dangle": 0,
@@ -31,7 +32,8 @@
"react/prop-types": 1,
"react/react-in-jsx-scope": 1,
"react/self-closing-comp": 1,
- "react/wrap-multilines": 1,
+ "react/jsx-wrap-multilines": 1,
+ "semi": ["error", "always"],
"strict": [1, "never"]
}
}
diff --git a/karma.conf.js b/karma.conf.js
index 072e5f3..63ac584 100644
--- a/karma.conf.js
+++ b/karma.conf.js
@@ -42,7 +42,7 @@ module.exports = function (config) {
autoWatch: true,
- browsers: [ isCI ? "PhantomJS" : "Chrome" ],
+ browsers: [isCI ? "PhantomJS" : "Chrome"],
captureTimeout: 60000,
browserNoActivityTimeout: 30000,
diff --git a/package.json b/package.json
index b1b960f..de24813 100644
--- a/package.json
+++ b/package.json
@@ -9,6 +9,7 @@
"scripts": {
"build": "rm -rf lib && babel src --out-dir lib",
"lint": "eslint ./",
+ "lint:fix": "eslint ./ --fix",
"test": "karma start --single-run",
"test-watch": "karma start",
"patch": "release patch --run",
@@ -49,9 +50,9 @@
"babel-runtime": "^6.0.0",
"chai": "^3.5.0",
"es5-shim": "^4.5.0",
- "eslint": "~1.6.0",
- "eslint-config-defaults": "~7.0.1",
- "eslint-plugin-react": "~3.5.1",
+ "eslint": "^3.17.1",
+ "eslint-config-defaults": "^9.0.0",
+ "eslint-plugin-react": "^6.10.0",
"karma": "~0.13.9",
"karma-chai": "~0.1.0",
"karma-chrome-launcher": "~0.2.0",
diff --git a/src/recaptcha-wrapper.js b/src/recaptcha-wrapper.js
index 5bedb2f..ce1561d 100644
--- a/src/recaptcha-wrapper.js
+++ b/src/recaptcha-wrapper.js
@@ -3,13 +3,13 @@ import makeAsyncScriptLoader from "react-async-script";
const callbackName = "onloadcallback";
const lang = typeof window !== "undefined" && (window.recaptchaOptions && window.recaptchaOptions.lang) ?
- "&hl=" + window.recaptchaOptions.lang :
+ `&hl=${window.recaptchaOptions.lang}` :
"";
const URL = `https://www.google.com/recaptcha/api.js?onload=${callbackName}&render=explicit${lang}`;
const globalName = "grecaptcha";
export default makeAsyncScriptLoader(ReCAPTCHA, URL, {
- callbackName: callbackName,
- globalName: globalName,
- exposeFuncs: ["getValue", "reset"],
+ callbackName,
+ globalName,
+ exposeFuncs: ["getValue", "reset", "execute"],
});
diff --git a/src/recaptcha.js b/src/recaptcha.js
index 400e978..6882942 100644
--- a/src/recaptcha.js
+++ b/src/recaptcha.js
@@ -10,15 +10,15 @@ const ReCAPTCHA = React.createClass({
type: PropTypes.oneOf(["image", "audio"]),
tabindex: PropTypes.number,
onExpired: PropTypes.func,
- size: PropTypes.oneOf(["compact", "normal"]),
+ size: PropTypes.oneOf(["compact", "normal", "invisible"]),
stoken: PropTypes.string,
},
- getInitialState() {
+ getInitialState () {
return {};
},
- getDefaultProps() {
+ getDefaultProps () {
return {
theme: "light",
type: "image",
@@ -27,20 +27,29 @@ const ReCAPTCHA = React.createClass({
};
},
- getValue() {
+ getValue () {
if (this.props.grecaptcha && this.state.widgetId !== undefined) {
return this.props.grecaptcha.getResponse(this.state.widgetId);
}
return null;
},
- reset() {
+ execute () {
+ const { grecaptcha } = this.props;
+ const { widgetId } = this.state;
+
+ if (grecaptcha && widgetId !== undefined) {
+ return grecaptcha.execute(widgetId);
+ }
+ },
+
+ reset () {
if (this.props.grecaptcha && this.state.widgetId !== undefined) {
this.props.grecaptcha.reset(this.state.widgetId);
}
},
- handleExpired() {
+ handleExpired () {
if (this.props.onExpired) {
this.props.onExpired();
} else if (this.props.onChange) {
@@ -48,9 +57,9 @@ const ReCAPTCHA = React.createClass({
}
},
- explicitRender(cb) {
+ explicitRender (cb) {
if (this.props.grecaptcha && this.state.widgetId === undefined) {
- let id = this.props.grecaptcha.render(this.refs.captcha, {
+ const id = this.props.grecaptcha.render(this.refs.captcha, {
sitekey: this.props.sitekey,
callback: this.props.onChange,
theme: this.props.theme,
@@ -66,15 +75,15 @@ const ReCAPTCHA = React.createClass({
}
},
- componentDidMount() {
+ componentDidMount () {
this.explicitRender();
},
- componentDidUpdate() {
+ componentDidUpdate () {
this.explicitRender();
},
- render() {
+ render () {
// consume properties owned by the reCATPCHA, pass the rest to the div so the user can style it.
/* eslint-disable no-unused-vars */
const { sitekey, onChange, theme, type, tabindex, onExpired, size, stoken, grecaptcha, ...childProps } = this.props;
diff --git a/test/recaptcha-spec.js b/test/recaptcha-spec.js
index 707b9c9..ff0c7ab 100644
--- a/test/recaptcha-spec.js
+++ b/test/recaptcha-spec.js
@@ -1,56 +1,72 @@
import React from "react";
import ReactDOM from "react-dom";
import ReactTestUtils from "react-addons-test-utils";
-import ReCAPTCHA from "../src/recaptcha";
+import ReCAPTCHA from "../src/recaptcha"; // eslint-disable-line no-unused-vars
describe("ReCAPTCHA", () => {
it("Rendered Component should be a div", () => {
- let instance = ReactTestUtils.renderIntoDocument(
-
- );
+ const instance = ReactTestUtils.renderIntoDocument(
+ ,
+ );
assert.equal(ReactDOM.findDOMNode(instance).nodeName, "DIV");
});
it("Rendered Component should contained passed props", () => {
- let props = {
+ const props = {
className: "TheClassName",
id: "superdefinedId",
};
- let instance = ReactTestUtils.renderIntoDocument(
-
- );
+ const instance = ReactTestUtils.renderIntoDocument(
+ ,
+ );
assert.equal(ReactDOM.findDOMNode(instance).id, props.id);
assert.match(ReactDOM.findDOMNode(instance).className, new RegExp(props.className));
});
it("should call grecaptcha.render, when it is already loaded", (done) => {
- let grecaptchaMock = {
- render(node, options) {
+ const grecaptchaMock = {
+ render (node, options) {
assert.isNotNull(node);
assert.equal(options.sitekey, "xxx");
done();
},
};
- let instance = ReactTestUtils.renderIntoDocument(
-
- );
+ const instance = ReactTestUtils.renderIntoDocument(
+ ,
+ );
assert.ok(instance);
});
it("reset, should call grecaptcha.reset with the widget id", (done) => {
- let grecaptchaMock = {
- render() {
+ const grecaptchaMock = {
+ render () {
return "someWidgetId";
},
- reset(widgetId) {
+ reset (widgetId) {
assert.isNotNull(widgetId);
done();
},
};
- let instance = ReactTestUtils.renderIntoDocument(
-
- );
+ const instance = ReactTestUtils.renderIntoDocument(
+ ,
+ );
instance.reset();
});
+ it("execute, should call grecaptcha.execute with the widget id", (done) => {
+ const grecaptchaMock = {
+ render () {
+ return "someWidgetId";
+ },
+
+ execute (widgetId) {
+ assert.isNotNull(widgetId);
+ done();
+ },
+ };
+ const instance = ReactTestUtils.renderIntoDocument(
+ ,
+ );
+ instance.execute();
+ });
describe("Expired", () => {
it("should call onChange with null when response is expired");
it("should call onExpired when response is expired");
diff --git a/test/recaptcha-wrapper-spec.js b/test/recaptcha-wrapper-spec.js
index f5dc57c..49f4af4 100644
--- a/test/recaptcha-wrapper-spec.js
+++ b/test/recaptcha-wrapper-spec.js
@@ -1,17 +1,17 @@
import React from "react";
import ReactTestUtils from "react-addons-test-utils";
-import ReCAPTCHA from "../src/recaptcha-wrapper";
+import ReCAPTCHA from "../src/recaptcha-wrapper"; // eslint-disable-line no-unused-vars
const VALUE = "some value";
const WIDGET_ID = "someWidgetId";
-let grecaptchaMock = {
- render(node, options) {
+const grecaptchaMock = {
+ render (node, options) {
assert.ok(node, options);
return WIDGET_ID;
},
- getResponse(widgetId) {
+ getResponse (widgetId) {
assert.equal(widgetId, WIDGET_ID);
return VALUE;
},
@@ -22,8 +22,8 @@ describe("ReCAPTCHAWrapper", () => {
window.grecaptcha = grecaptchaMock;
});
it("should proxy functions", () => {
- let instance = ReactTestUtils.renderIntoDocument(
-
+ const instance = ReactTestUtils.renderIntoDocument(
+ ,
);
assert.ok(instance);
assert.equal(instance.getValue(), VALUE);