<commit_before>
#include "StdAfx.h"
#include "ElementWrapper.h"
#include "utils.h"
#include <iostream>

using namespace std;

#include <comutil.h>
#include <comdef.h>

ElementWrapper::ElementWrapper(InternetExplorerDriver* ie, IHTMLDOMNode* node)
{
	node->QueryInterface(__uuidof(IHTMLElement), (void**)&element);
	this->ie = ie;
}

ElementWrapper::~ElementWrapper()
{
	element->Release();
}

const wchar_t* ElementWrapper::getAttribute(const wchar_t* name) 
{
	wchar_t *lookFor = (wchar_t *)name;

	if (_wcsicmp(L"class", name) == 0) {
		lookFor = L"className";
	}

	BSTR attributeName = SysAllocString(lookFor);
	VARIANT value;
	element->getAttribute(attributeName, 0, &value);
	const wchar_t* toReturn = variant2wchar(value);
	VariantClear(&value);
	return toReturn;
}

const wchar_t* ElementWrapper::getValue()
{
	BSTR temp;
	element->get_tagName(&temp);
	const wchar_t *name = bstr2wchar(temp);
	SysFreeString(temp);

	int value = _wcsicmp(L"textarea", name);
	delete name;

	if (value == 0) 
		return this->getTextAreaValue();
	return this->getAttribute(L"value");
}

InternetExplorerDriver* ElementWrapper::setValue(wchar_t* newValue)
{
	IDispatch* dispatch;
	element->get_document(&dispatch);
	CComQIPtr<IHTMLDocument4, &__uuidof(IHTMLDocument4)> doc = dispatch;
	dispatch->Release();
	CComQIPtr<IHTMLElement3, &__uuidof(IHTMLElement3)> element3 = element;

	VARIANT empty;
	VariantInit(&empty);

	size_t length = wcslen(newValue);

	CComBSTR valueAttributeName = SysAllocString(L"value");
	VARIANT reallyNewValue;
	VariantInit(&reallyNewValue);
	reallyNewValue.vt = VT_BSTR;
	reallyNewValue.bstrVal = SysAllocString(L"");
	element->setAttribute(valueAttributeName, reallyNewValue, 0);
	VariantClear(&reallyNewValue);

	CComBSTR onKeyDown = SysAllocString(L"onkeydown");
	CComBSTR onKeyPress = SysAllocString(L"onkeypress");
	CComBSTR onKeyUp = SysAllocString(L"onkeyup");
	VARIANT_BOOL cancellable;

	for (size_t i = 0; i < length; i++) {
		VariantInit(&reallyNewValue);
		reallyNewValue.vt = VT_BSTR;
		wchar_t* t = new wchar_t[i+2];
		wcsncpy_s(t, i+2, newValue, i+1);
		t[i+1] = '\0';
		reallyNewValue.bstrVal = SysAllocString(t);

		IHTMLEventObj* eventObject;
		doc->createEventObject(&empty, &eventObject);
		eventObject->put_keyCode((long) newValue[i]);

		VARIANT eventref;
		VariantInit(&eventref);
		V_VT(&eventref) = VT_DISPATCH;
		V_DISPATCH(&eventref) = eventObject;


        element3->fireEvent(onKeyDown, &eventref, &cancellable);
        element3->fireEvent(onKeyPress, &eventref, &cancellable);
		element->setAttribute(valueAttributeName, reallyNewValue, 0);
        element3->fireEvent(onKeyUp, &eventref, &cancellable);

		delete t;
		VariantClear(&eventref);
		VariantClear(&reallyNewValue);
	}

	VariantClear(&reallyNewValue);

	return new InternetExplorerDriver(ie);
}

bool ElementWrapper::isSelected()
{
	IHTMLOptionElement* option = NULL;
	element->QueryInterface(__uuidof(IHTMLOptionElement), (void**)&option);
	if (option != NULL) {
		VARIANT_BOOL isSelected;
		option->get_selected(&isSelected);
		option->Release();
		return isSelected == VARIANT_TRUE;
	}

	if (isCheckbox()) {
		IHTMLInputElement* input;
		element->QueryInterface(__uuidof(IHTMLInputElement), (void**)&input);
		VARIANT_BOOL isChecked;
		input->get_checked(&isChecked);
		input->Release();
<commit_msg>SimonStewart: Better event firing when setting an element's value using the ie driver<commit_after>
#include "StdAfx.h"
#include "ElementWrapper.h"
#include "utils.h"
#include <iostream>

using namespace std;

#include <comutil.h>
#include <comdef.h>

ElementWrapper::ElementWrapper(InternetExplorerDriver* ie, IHTMLDOMNode* node)
{
	node->QueryInterface(__uuidof(IHTMLElement), (void**)&element);
	this->ie = ie;
}

ElementWrapper::~ElementWrapper()
{
	element->Release();
}

const wchar_t* ElementWrapper::getAttribute(const wchar_t* name) 
{
	wchar_t *lookFor = (wchar_t *)name;

	if (_wcsicmp(L"class", name) == 0) {
		lookFor = L"className";
	}

	BSTR attributeName = SysAllocString(lookFor);
	VARIANT value;
	element->getAttribute(attributeName, 0, &value);
	const wchar_t* toReturn = variant2wchar(value);
	VariantClear(&value);
	return toReturn;
}

const wchar_t* ElementWrapper::getValue()
{
	BSTR temp;
	element->get_tagName(&temp);
	const wchar_t *name = bstr2wchar(temp);
	SysFreeString(temp);

	int value = _wcsicmp(L"textarea", name);
	delete name;

	if (value == 0) 
		return this->getTextAreaValue();
	return this->getAttribute(L"value");
}

InternetExplorerDriver* ElementWrapper::setValue(wchar_t* newValue)
{
	CComQIPtr<IHTMLElement2, &__uuidof(IHTMLElement2)> element2 = element;

	IDispatch* dispatch;
	element->get_document(&dispatch);
	CComQIPtr<IHTMLDocument4, &__uuidof(IHTMLDocument4)> doc = dispatch;
	dispatch->Release();
	CComQIPtr<IHTMLElement3, &__uuidof(IHTMLElement3)> element3 = element;

	VARIANT empty;
	VariantInit(&empty);

	size_t length = wcslen(newValue);

	CComBSTR valueAttributeName = SysAllocString(L"value");
	VARIANT reallyNewValue;
	VariantInit(&reallyNewValue);
	reallyNewValue.vt = VT_BSTR;
	reallyNewValue.bstrVal = SysAllocString(L"");
	element->setAttribute(valueAttributeName, reallyNewValue, 0);
	VariantClear(&reallyNewValue);

	CComBSTR onKeyDown = SysAllocString(L"onkeydown");
	CComBSTR onKeyPress = SysAllocString(L"onkeypress");
	CComBSTR onKeyUp = SysAllocString(L"onkeyup");
	VARIANT_BOOL cancellable;

	element2->focus();

	for (size_t i = 0; i < length; i++) {
		VariantInit(&reallyNewValue);
		reallyNewValue.vt = VT_BSTR;
		wchar_t* t = new wchar_t[i+2];
		wcsncpy_s(t, i+2, newValue, i+1);
		t[i+1] = '\0';
		reallyNewValue.bstrVal = SysAllocString(t);

		IHTMLEventObj* eventObject;
		doc->createEventObject(&empty, &eventObject);
		eventObject->put_keyCode((long) newValue[i]);

		VARIANT eventref;
		VariantInit(&eventref);
		V_VT(&eventref) = VT_DISPATCH;
		V_DISPATCH(&eventref) = eventObject;


        element3->fireEvent(onKeyDown, &eventref, &cancellable);
        element3->fireEvent(onKeyPress, &eventref, &cancellable);
		element->setAttribute(valueAttributeName, reallyNewValue, 0);
        element3->fireEvent(onKeyUp, &eventref, &cancellable);

		delete t;
		VariantClear(&eventref);
		VariantClear(&reallyNewValue);
	}
	element2->blur();

	IHTMLEventObj* eventObj = newEventObject();
	fireEvent(eventObj, L"onchange");
	eventObj->Release();

	VariantClear(&reallyNewValue);

	return new InternetExplorerDriver(ie);
}

bool ElementWrapper::isSelected()
{
	IHTMLOptionElement* option = NULL;
	element->QueryInterface(__uuidof(IHTMLOptionElement), (void**)&option);
	if (option != NULL) {
		VARIANT_BOOL isSelected;
		option->get_selected(&isSelected);
		option->Release();
		return isSelected == VARIANT_TRUE;
	}

	if (isCheckbox()) {
		IHTMLInputElement* input;
		element->QueryInterface(__uuidof(IHTMLInputElement), (void**)&input);
		VARIANT_BOOL isChecked;
		input->get_checked(&isChecked);
		input->Release();

{'fraction_non_alphanumeric': 0.13900955690703737, 'fraction_numerical': 0.006805676223573704, 'mean_word_length': 6.483206933911159, 'pattern_counts': {'":': 0, '<': 16, '<?xml version=': 0, '>': 61, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3830999', 'n_tokens_mistral': 2594, 'n_tokens_neox': 2458, 'n_words': 440}