Path: blob/trunk/cpp/iedriver/CommandHandlers/ExecuteAsyncScriptCommandHandler.cpp
2868 views
// Licensed to the Software Freedom Conservancy (SFC) under one1// or more contributor license agreements. See the NOTICE file2// distributed with this work for additional information3// regarding copyright ownership. The SFC licenses this file4// to you under the Apache License, Version 2.0 (the "License");5// you may not use this file except in compliance with the License.6// You may obtain a copy of the License at7//8// http://www.apache.org/licenses/LICENSE-2.09//10// Unless required by applicable law or agreed to in writing, software11// distributed under the License is distributed on an "AS IS" BASIS,12// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.13// See the License for the specific language governing permissions and14// limitations under the License.1516#include "ExecuteAsyncScriptCommandHandler.h"17#include "errorcodes.h"18#include "../Browser.h"19#include "../IECommandExecutor.h"20#include "../Script.h"21#include "../StringUtilities.h"2223#define GUID_STRING_LEN 402425namespace webdriver {2627ExecuteAsyncScriptCommandHandler::ExecuteAsyncScriptCommandHandler(void) {28}2930ExecuteAsyncScriptCommandHandler::~ExecuteAsyncScriptCommandHandler(void) {31}3233void ExecuteAsyncScriptCommandHandler::ExecuteInternal(34const IECommandExecutor& executor,35const ParametersMap& command_parameters,36Response* response) {37ParametersMap::const_iterator script_parameter_iterator = command_parameters.find("script");38ParametersMap::const_iterator args_parameter_iterator = command_parameters.find("args");39if (script_parameter_iterator == command_parameters.end()) {40response->SetErrorResponse(ERROR_INVALID_ARGUMENT,41"Missing parameter: script");42return;43}4445if (!script_parameter_iterator->second.isString()) {46response->SetErrorResponse(ERROR_INVALID_ARGUMENT,47"script parameter must be a string");48return;49}5051if (args_parameter_iterator == command_parameters.end()) {52response->SetErrorResponse(ERROR_INVALID_ARGUMENT,53"Missing parameter: args");54return;55}5657if (!args_parameter_iterator->second.isArray()) {58response->SetErrorResponse(ERROR_INVALID_ARGUMENT,59"args parameter must be an array");60return;61}6263std::vector<wchar_t> page_id_buffer(GUID_STRING_LEN);64GUID page_id_guid;65::CoCreateGuid(&page_id_guid);66::StringFromGUID2(page_id_guid, &page_id_buffer[0], GUID_STRING_LEN);67std::wstring page_id = &page_id_buffer[0];6869std::vector<wchar_t> pending_id_buffer(GUID_STRING_LEN);70GUID pending_id_guid;71::CoCreateGuid(&pending_id_guid);72::StringFromGUID2(pending_id_guid, &pending_id_buffer[0], GUID_STRING_LEN);73std::wstring pending_id = &pending_id_buffer[0];7475Json::Value json_args = args_parameter_iterator->second;7677unsigned long long timeout_value = executor.async_script_timeout();78std::wstring timeout = std::to_wstring(static_cast<long long>(timeout_value));7980std::wstring script_body = StringUtilities::ToWString(script_parameter_iterator->second.asString());8182std::wstring async_script = L"(function() { return function(){\n";83async_script += L"document.__$webdriverAsyncExecutor = {\n";84async_script += L" pageId: '" + page_id + L"',\n";85async_script += L" asyncTimeout: 0\n";86async_script += L"};\n";87async_script += L"var timeoutId = window.setTimeout(function() {\n";88async_script += L" window.setTimeout(function() {\n";89async_script += L" document.__$webdriverAsyncExecutor.asyncTimeout = 1;\n";90async_script += L" }, 0);\n";91async_script += L"}," + timeout + L");\n";92async_script += L"var callback = function(value) {\n";93async_script += L" document.__$webdriverAsyncExecutor.asyncTimeout = 0;\n";94async_script += L" document.__$webdriverAsyncExecutor.asyncScriptResult = value;\n";95async_script += L" window.clearTimeout(timeoutId);\n";96async_script += L"};\n";97async_script += L"var argsArray = Array.prototype.slice.call(arguments);\n";98async_script += L"argsArray.push(callback);\n";99async_script += L"if (document.__$webdriverAsyncExecutor.asyncScriptResult !== undefined) {\n";100async_script += L" delete document.__$webdriverAsyncExecutor.asyncScriptResult;\n";101async_script += L"}\n";102async_script += L"(function() {\n" + script_body + L"\n}).apply(null, argsArray);\n";103async_script += L"};})();";104105std::wstring polling_script = L"(function() { return function(){\n";106polling_script += L"var pendingId = '" + pending_id + L"';\n";107polling_script += L"if ('__$webdriverAsyncExecutor' in document) {\n";108polling_script += L" if (document.__$webdriverAsyncExecutor.pageId != '" + page_id + L"') {\n";109polling_script += L" return {'status': 'reload', 'id': pendingId, 'value': -1};\n";110polling_script += L" } else if ('asyncScriptResult' in document.__$webdriverAsyncExecutor) {\n";111polling_script += L" var value = document.__$webdriverAsyncExecutor.asyncScriptResult;\n";112polling_script += L" delete document.__$webdriverAsyncExecutor.asyncScriptResult;\n";113polling_script += L" return {'status': 'complete', 'id': pendingId, 'value': value};\n";114polling_script += L" } else if (document.__$webdriverAsyncExecutor.asyncTimeout == 0) {\n";115polling_script += L" return {'status': 'pending', 'id': pendingId, 'value': document.__$webdriverAsyncExecutor.asyncTimeout};\n";116polling_script += L" } else {\n";117polling_script += L" return {'status': 'timeout', 'id': pendingId, 'value': document.__$webdriverAsyncExecutor.asyncTimeout};\n";118polling_script += L" }\n";119polling_script += L"} else {\n";120polling_script += L" return {'status': 'reload', 'id': pendingId, 'value': -1};\n";121polling_script += L"}\n";122polling_script += L"};})();";123124BrowserHandle browser_wrapper;125int status_code = executor.GetCurrentBrowser(&browser_wrapper);126if (status_code != WD_SUCCESS) {127response->SetErrorResponse(status_code, "Unable to get browser");128return;129}130131CComPtr<IHTMLDocument2> doc;132browser_wrapper->GetDocument(&doc);133134HWND async_executor_handle;135Script async_script_wrapper(doc, async_script);136async_script_wrapper.set_polling_source_code(polling_script);137status_code = async_script_wrapper.ExecuteAsync(executor,138json_args,139&async_executor_handle);140browser_wrapper->set_script_executor_handle(async_executor_handle);141142if (status_code != WD_SUCCESS) {143response->SetErrorResponse(status_code, "JavaScript error");144}145}146147} // namespace webdriver148149150