forked from SeleniumHQ/selenium
-
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathElementRepository.cpp
141 lines (119 loc) · 5.28 KB
/
ElementRepository.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
// Licensed to the Software Freedom Conservancy (SFC) under one
// or more contributor license agreements. See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership. The SFC licenses this file
// to you under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include "ElementRepository.h"
#include "logging.h"
#include "errorcodes.h"
#include "Element.h"
namespace webdriver {
ElementRepository::ElementRepository(void) {
}
ElementRepository::~ElementRepository(void) {
}
int ElementRepository::GetManagedElement(const std::string& element_id,
ElementHandle* element_wrapper) const {
LOG(TRACE) << "Entering ElementRepository::GetManagedElement";
ElementMap::const_iterator found_iterator = this->managed_elements_.find(element_id);
if (found_iterator == this->managed_elements_.end()) {
LOG(DEBUG) << "Unable to find managed element with id " << element_id;
return ENOSUCHELEMENT;
}
*element_wrapper = found_iterator->second;
return WD_SUCCESS;
}
bool ElementRepository::AddManagedElement(ElementHandle element_wrapper) {
this->managed_elements_[element_wrapper->element_id()] = element_wrapper;
return true;
}
bool ElementRepository::AddManagedElement(BrowserHandle current_browser,
IHTMLElement* element,
ElementHandle* element_wrapper) {
LOG(TRACE) << "Entering ElementRepository::AddManagedElement";
bool element_already_managed = this->IsElementManaged(element, element_wrapper);
if (!element_already_managed) {
LOG(DEBUG) << "Element is not yet managed";
HWND containing_window_handle = NULL;
if (current_browser != NULL) {
containing_window_handle = current_browser->GetContentWindowHandle();
}
ElementHandle new_wrapper(new Element(element,
containing_window_handle));
this->managed_elements_[new_wrapper->element_id()] = new_wrapper;
*element_wrapper = new_wrapper;
} else {
LOG(DEBUG) << "Element is already managed";
}
return !element_already_managed;
}
bool ElementRepository::IsElementManaged(IHTMLElement* element,
ElementHandle* element_wrapper) {
// TODO: This method needs much work. If we are already managing a
// given element, we don't want to assign it a new ID, but to find
// out if we're managing it already, we need to compare to all of
// the elements already in our map, which means iterating through
// the map. For long-running tests, this means the addition of a
// new managed element may take longer and longer as we have no
// good algorithm for removing dead elements from the map.
ElementMap::iterator it = this->managed_elements_.begin();
for (; it != this->managed_elements_.end(); ++it) {
if (it->second->element() == element) {
*element_wrapper = it->second;
return true;
}
}
return false;
}
void ElementRepository::RemoveManagedElement(const std::string& element_id) {
LOG(TRACE) << "Entering ElementRepository::RemoveManagedElement";
ElementMap::iterator found_iterator = this->managed_elements_.find(element_id);
if (found_iterator != this->managed_elements_.end()) {
this->managed_elements_.erase(element_id);
} else {
LOG(DEBUG) << "Unable to find element to remove with id " << element_id;
}
}
void ElementRepository::ListManagedElements() {
LOG(TRACE) << "Entering ElementRepository::ListManagedElements";
ElementMap::iterator it = this->managed_elements_.begin();
for (; it != this->managed_elements_.end(); ++it) {
LOG(DEBUG) << "Managed element: " << it->first;
}
}
void ElementRepository::ClearCache() {
// Logic explanation: We can't just remove the elements from the
// managed elements map, within the loop as that would invalidate
// the iterator. So we add the keys to a vector, and use the vector
// to remove the elements from the map.
std::vector<std::string> bad_elements;
ElementMap::const_iterator managed_iterator = this->managed_elements_.begin();
ElementMap::const_iterator last_managed_element = this->managed_elements_.end();
for(; managed_iterator != last_managed_element; ++managed_iterator) {
if (!managed_iterator->second->IsAttachedToDom()) {
bad_elements.push_back(managed_iterator->first);
}
}
LOG(DEBUG) << "Refreshing managed element cache. Found "
<< bad_elements.size()
<< " to remove from cache.";
std::vector<std::string>::const_iterator id_iterator = bad_elements.begin();
std::vector<std::string>::const_iterator last_id = bad_elements.end();
for (; id_iterator != last_id; ++id_iterator) {
this->RemoveManagedElement(*id_iterator);
}
}
void ElementRepository::Clear() {
this->managed_elements_.clear();
}
} // namespace webdriver