diff --git a/src/modules/webpage.js b/src/modules/webpage.js index 47c1e82563..0678107234 100644 --- a/src/modules/webpage.js +++ b/src/modules/webpage.js @@ -187,6 +187,30 @@ exports.create = function (opts) { this._appendScriptElement(scriptUrl); }; + /** + * evaluate a function in the page + * @param {function} func the function to evaluate + * @param {...} args function arguments + * @return {*} the function call result + */ + page.evaluate = function (func, args) { + var str, arg, i, l; + if (!(func instanceof Function || typeof func === 'string' || func instanceof String)) { + throw "Wrong use of WebPage#evaluate"; + } + str = 'function() { return (' + func.toString() + ')('; + for (i = 1, l = arguments.length; i < l; i++) { + arg = arguments[i]; + if (/object|string/.test(typeof arg) && !(arg instanceof RegExp)) { + str += 'JSON.parse(' + JSON.stringify(JSON.stringify(arg)) + '),'; + } else { + str += arg + ','; + } + } + str = str.replace(/,$/, '') + '); }'; + return this.evaluateJavaScript(str); + } + // Copy options into page if (opts) { page = copyInto(page, opts); diff --git a/src/webpage.cpp b/src/webpage.cpp index 7bc3784680..426a617322 100644 --- a/src/webpage.cpp +++ b/src/webpage.cpp @@ -291,7 +291,7 @@ QVariantMap WebPage::paperSize() const return m_paperSize; } -QVariant WebPage::evaluate(const QString &code) +QVariant WebPage::evaluateJavaScript(const QString &code) { QString function = "(" + code + ")()"; return m_mainFrame->evaluateJavaScript(function, QString("phantomjs://webpage.evaluate()")); diff --git a/src/webpage.h b/src/webpage.h index c9dcacaccc..f6b0a80576 100644 --- a/src/webpage.h +++ b/src/webpage.h @@ -89,7 +89,7 @@ public slots: void openUrl(const QString &address, const QVariant &op, const QVariantMap &settings); void release(); - QVariant evaluate(const QString &code); + QVariant evaluateJavaScript(const QString &code); bool render(const QString &fileName); bool injectJs(const QString &jsFilePath); void _appendScriptElement(const QString &scriptUrl); diff --git a/test/webpage-spec.js b/test/webpage-spec.js index 07ddea37b4..f2048fd97e 100644 --- a/test/webpage-spec.js +++ b/test/webpage-spec.js @@ -323,6 +323,65 @@ describe("WebPage object", function() { }); }); + + it("should pass variables to functions properly", function() { + var testPrimitiveArgs = function() { + var samples = [ + true, + 0, + "`~!@#$%^&*()_+-=[]\{}|;':\",./<>?", + undefined, + null + ]; + for (var i = 0; i < samples.length; i++) { + if (samples[i] !== arguments[i]) { + console.log("FAIL"); + } + } + }; + + var testComplexArgs = function() { + var samples = [ + {a:true, b:0, c:"string"}, + function() { return true; }, + [true, 0, "string"], + /\d+\w*\// + ]; + for (var i = 0; i < samples.length; i++) { + if (typeof samples[i] !== typeof arguments[i] + || samples[i].toString() !== arguments[i].toString()) { + console.log("FAIL"); + } + } + }; + + var message; + runs(function() { + page.onConsoleMessage = function (msg) { + message = msg; + } + }); + + waits(0); + + runs(function() { + page.evaluate(function() { + console.log("PASS"); + }); + page.evaluate(testPrimitiveArgs, + true, + 0, + "`~!@#$%^&*()_+-=[]\{}|;':\",./<>?", + undefined, + null); + page.evaluate(testComplexArgs, + {a:true, b:0, c:"string"}, + function() { return true; }, + [true, 0, "string"], + /\d+\w*\//); + expect(message).toEqual("PASS"); + }); + }); }); describe("WebPage construction with options", function () {