marta 0.31813 → 0.31831

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 1b4fe8f6b3ddacabb9ee5feba5d3c203f08a26cb
4
- data.tar.gz: 57cbf028c9088b41a80e8281aa943a084fbe66d6
3
+ metadata.gz: 5194e2abdec5dea63de3729eded639658cd5e4c4
4
+ data.tar.gz: 3c246346272294bb585cad04e824ad3f0c271887
5
5
  SHA512:
6
- metadata.gz: e2b37b9b074afe23940c0949028c1a65eee3931fbaed832c4fca5c8de9e42da36dcf3f5516673a8908d5eb21ad15bc374de969c040f13e1e7483bb7a118d7b75
7
- data.tar.gz: e003e723ea5d48d563b05b0e2d88d2fade5d2ccdd7de78caf2fe974f7622e91c088a4885e10239f69107108b1e618c4f1d8420a5831f7451acfc1b936fdeb942
6
+ metadata.gz: 5afbf7645596d47577731e8e3898e6c2e8a96e575900d0832798cdd0a9ced60430fc70b3afa2e284b1999d721ab150fe7f2e7ac75f4d14c51ec0b57e46b38ca3
7
+ data.tar.gz: 860e8de97e4f32469897609fedad639d26864b6503706532f88d2057f122a40bf8d6506f1077adb77ec1f81db00753dde0001fff444a3fab14b1c51379c4f172
data/README.md CHANGED
@@ -139,7 +139,7 @@ test_page = SmartPage.new("TestPage")
139
139
  test_page.method_edit("magic_button")
140
140
  ```
141
141
 
142
- **Q: Sometimes Marta is looking for lost element for too long. What can I do about it?**
142
+ **Q: Sometimes Marta is looking for the lost element for too long. What can I do about it?**
143
143
 
144
144
  *A: You can set tolerancy parameter. Larger = longer*
145
145
  ```ruby
@@ -147,6 +147,13 @@ dance_with tolerancy: 1024# is the default value
147
147
  ```
148
148
  *That logic will be changed to more understandable soon. I hope.*
149
149
 
150
+ **Q: Marta is trying to find the lost element after pretty long time. Why?**
151
+
152
+ *A: Marta is not starting active search for the element immediately because she hopes that the element will appear (created by js). By default marta is waiting for the element for 10 seconds. But if you are sure that it is too long (or maybe too short) you can change that waiting time like:*
153
+ ```ruby
154
+ dance_with cold_timeout: 5
155
+ ```
156
+
150
157
  **Q: How can I get Watir browser instance if I want for example execute_script or find element without Marta?**
151
158
 
152
159
  *A: Like that*
@@ -240,7 +247,7 @@ g_page.search "I am in love with selenium."
240
247
 
241
248
  **Q: What else?**
242
249
 
243
- *A: Nothing. Marta is under development. Her version is 0.31813 only. And I am not a professional developer. But I am training her on new tricks.*
250
+ *A: Nothing. Marta is under development. Her version is 0.31831 only. And I am not a professional developer. But I am training her on new tricks.*
244
251
 
245
252
  ## Internal Design
246
253
 
@@ -1,5 +1,6 @@
1
1
  require 'marta/x_path'
2
2
  require 'marta/simple_element_finder'
3
+ require 'marta/options_and_paths'
3
4
 
4
5
  module Marta
5
6
 
@@ -15,7 +16,7 @@ module Marta
15
16
  # becoming larger than tolerancy value
16
17
  module BlackMagic
17
18
 
18
- include XPath, SimpleElementFinder
19
+ include XPath, SimpleElementFinder, OptionsAndPaths
19
20
 
20
21
  private
21
22
 
@@ -25,6 +26,8 @@ module Marta
25
26
  # @note It is believed that no user will use it
26
27
  class MagicFinder < BasicFinder
27
28
 
29
+ include OptionsAndPaths
30
+
28
31
  def initialize(meth, tolerancy, requestor)
29
32
  @tolerancy = tolerancy
30
33
  @engine = requestor.engine
@@ -34,7 +37,7 @@ module Marta
34
37
  # We can prefind an element and wait for it.
35
38
  def prefind_with_waiting
36
39
  begin
37
- prefind.wait_until_present(timeout: 10)
40
+ prefind.wait_until_present(timeout: SettingMaster.cold_timeout)
38
41
  rescue
39
42
  # found nothing
40
43
  prefind
@@ -3,7 +3,7 @@
3
3
  <div martaclass=marta_smthing martastyle=header>
4
4
  <h2 id=marta_main_title martaclass=marta_smthing></h2>
5
5
  <div martastyle=icons_holder martaclass=marta_smthing>
6
- <input type=button martaclass=marta_smthing martastyle=icon_button id=marta_hide onclick=marta_hide(); value=&#x21E8; />
6
+ <input type=button martaclass=marta_smthing martastyle=icon_button id=marta_hide value=&#x21E8; />
7
7
  </div>
8
8
  </div>
9
9
  <div martaclass=marta_smthing martastyle=hint>
@@ -21,14 +21,14 @@
21
21
  </label>
22
22
  </div>
23
23
  <div martastyle=buttons_holder martaclass=marta_smthing>
24
- <input type=button martaclass=marta_smthing id=marta_try_again martastyle=action_button onclick=marta_try_again(); value="Try again" />
25
- <input type=button martaclass=marta_smthing id=marta_confirm martastyle=confirm_button onclick=marta_confirm(); value=Confirm />
24
+ <input type=button martaclass=marta_smthing id=marta_try_again martastyle=action_button value="Try again" />
25
+ <input type=button martaclass=marta_smthing id=marta_confirm martastyle=confirm_button value=Confirm />
26
26
  </div>
27
27
  </div>
28
28
  <div id=xpath_field martaclass=marta_smthing>
29
29
  <div martaclass=marta_smthing class=label id=marta_xpath_label>Set XPATH here and hit Enter.</div>
30
30
  <span martaclass=marta_smthing>XPATH:
31
- <input onchange=marta_look(); type=text id=marta_user_xpath martaclass=marta_smthing value=//>
31
+ <input type=text id=marta_user_xpath martaclass=marta_smthing value=//>
32
32
  </span>
33
33
  </div>
34
34
  </hr>
@@ -1,21 +1,26 @@
1
- var marta_result = {};
2
- var marta_confirm_mark = false;
3
- var marta_temp_els =[];
1
+ document.marta_result = {};
2
+ document.marta_confirm_mark = false;
3
+ document.marta_temp_els =[];
4
4
 
5
- function marta_add_data() {
6
- marta_confirm_mark = false;
7
- document.getElementById("marta_main_title").innerHTML = "XPATH for " + marta_what + " = ?";
5
+ document.getElementById("marta_try_again").onclick = function() {document.marta_try_again()};
6
+ document.getElementById("marta_confirm").onclick = function() {document.marta_confirm()};
7
+ document.getElementById("marta_user_xpath").onchange = function() {document.marta_look()};
8
+ document.getElementById("marta_hide").onclick = function() {document.marta_hide()};
9
+
10
+ document.marta_add_data = function() {
11
+ document.marta_confirm_mark = false;
12
+ document.getElementById("marta_main_title").innerHTML = "XPATH for " + document.marta_what + " = ?";
8
13
  };
9
14
 
10
- function marta_look() {
15
+ document.marta_look = function() {
11
16
  try {
12
- for (var i=0; i<marta_temp_els.snapshotLength; i++) {
13
- marta_temp_els.snapshotItem(i).removeAttribute("martaclass");
17
+ for (var i=0; i<document.marta_temp_els.snapshotLength; i++) {
18
+ document.marta_temp_els.snapshotItem(i).removeAttribute("martaclass");
14
19
  };
15
20
  var t=0;
16
21
  var value = document.getElementById("marta_user_xpath").value;
17
22
  var result = document.evaluate(value, document.body, null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null);
18
- marta_temp_els = result;
23
+ document.marta_temp_els = result;
19
24
  for (var i=0; i<result.snapshotLength; i++) {
20
25
  var marta_smthing = ((result.snapshotItem(i).getAttribute("martaclass")=="marta_smthing")||(result.snapshotItem(i).getAttribute("martaclass")=="marta_div"));
21
26
  if(!marta_smthing) {
@@ -29,28 +34,28 @@ function marta_look() {
29
34
  };
30
35
  };
31
36
 
32
- function marta_confirm(){
33
- for (var i=0; i<marta_temp_els.snapshotLength; i++) {
34
- marta_temp_els.snapshotItem(i).removeAttribute("martaclass");
37
+ document.marta_confirm = function(){
38
+ for (var i=0; i<document.marta_temp_els.snapshotLength; i++) {
39
+ document.marta_temp_els.snapshotItem(i).removeAttribute("martaclass");
35
40
  };
36
- marta_result["collection"] = document.getElementById("marta_array").checked;
37
- marta_result["xpath"] = document.getElementById("marta_user_xpath").value;
41
+ document.marta_result["collection"] = document.getElementById("marta_array").checked;
42
+ document.marta_result["xpath"] = document.getElementById("marta_user_xpath").value;
38
43
  var toClear = document.querySelector("[martaclass=marta_smthing]");
39
44
  toClear.parentNode.removeChild(toClear);
40
- marta_confirm_mark = true;
45
+ document.marta_confirm_mark = true;
41
46
  };
42
47
 
43
- function marta_try_again(){
44
- for (var i=0; i<marta_temp_els.snapshotLength; i++) {
45
- marta_temp_els.snapshotItem(i).removeAttribute("martaclass");
48
+ document.marta_try_again = function(){
49
+ for (var i=0; i<document.marta_temp_els.snapshotLength; i++) {
50
+ document.marta_temp_els.snapshotItem(i).removeAttribute("martaclass");
46
51
  };
47
52
  var toClear = document.querySelector("[martaclass=marta_div]");
48
53
  toClear.parentNode.removeChild(toClear);
49
- marta_confirm_mark = true;
50
- marta_result = "2";
54
+ document.marta_confirm_mark = true;
55
+ document.marta_result = "2";
51
56
  };
52
57
 
53
- function marta_hide() {
58
+ document.marta_hide = function() {
54
59
  var toHide = document.querySelector("[martaclass=marta_div]");
55
60
  if (toHide.getAttribute("martastyle")=="hidden"){
56
61
  toHide.setAttribute("martastyle", "none");
@@ -3,7 +3,7 @@
3
3
  <div martaclass=marta_smthing martastyle=header>
4
4
  <h2 id=marta_main_title martaclass=marta_smthing></h2>
5
5
  <div martastyle=icons_holder martaclass=marta_smthing>
6
- <input type=button martaclass=marta_smthing martastyle=icon_button id=marta_hide onclick=marta_hide(); value=&#x21E8; />
6
+ <input type=button martaclass=marta_smthing martastyle=icon_button id=marta_hide value=&#x21E8; />
7
7
  </div>
8
8
  </div>
9
9
  <div martaclass=marta_smthing martastyle=hint>
@@ -16,9 +16,9 @@
16
16
  </div>
17
17
  <div id=marta_s_content martaclass=marta_smthing>
18
18
  <div martastyle=buttons_holder martaclass=marta_smthing>
19
- <input type=button martaclass=marta_smthing martastyle=confirm_button id=marta_confirm onclick=marta_confirm(); value=Confirm />
20
- <input type=button martaclass=marta_smthing martastyle=cancel_button id=marta_try_again onclick=marta_try_again(); value="Try again" />
21
- <input type=button martaclass=marta_smthing martastyle=action_button id=marta_set_by_hand onclick=marta_set_by_hand(); value="Set by hand" />
19
+ <input type=button martaclass=marta_smthing martastyle=confirm_button id=marta_confirm value=Confirm />
20
+ <input type=button martaclass=marta_smthing martastyle=cancel_button id=marta_try_again value="Try again" />
21
+ <input type=button martaclass=marta_smthing martastyle=action_button id=marta_set_by_hand value="Set by hand" />
22
22
  </div>
23
23
  </div>
24
24
  <div id=attr_fields martaclass=marta_smthing>
@@ -1,35 +1,40 @@
1
- var marta_result = {};
2
- var marta_confirm_mark = false;
1
+ document.marta_result = {};
2
+ document.marta_confirm_mark = false;
3
3
 
4
- function marta_confirm(){
4
+ document.getElementById("marta_try_again").onclick = function() {document.marta_try_again()};
5
+ document.getElementById("marta_confirm").onclick = function() {document.marta_confirm()};
6
+ document.getElementById("marta_set_by_hand").onclick = function() {document.marta_set_by_hand()};
7
+ document.getElementById("marta_hide").onclick = function() {document.marta_hide()};
8
+
9
+ document.marta_confirm = function(){
5
10
  var toClear = document.querySelector("[martaclass=marta_smthing]");
6
11
  toClear.parentNode.removeChild(toClear);
7
- marta_confirm_mark = true;
8
- marta_result = "4";
12
+ document.marta_confirm_mark = true;
13
+ document.marta_result = "4";
9
14
  };
10
15
 
11
- function marta_click_work(e){};
16
+ document.marta_click_work = function(e){};
12
17
 
13
- function marta_try_again(){
18
+ document.marta_try_again = function(){
14
19
  var toClear = document.querySelector("[martaclass=marta_div]");
15
20
  toClear.parentNode.removeChild(toClear);
16
- marta_confirm_mark = true;
17
- marta_result = "2";
21
+ document.marta_confirm_mark = true;
22
+ document.marta_result = "2";
18
23
  };
19
24
 
20
- function marta_set_by_hand(){
25
+ document.marta_set_by_hand = function(){
21
26
  var toClear = document.querySelector("[martaclass=marta_div]");
22
27
  toClear.parentNode.removeChild(toClear);
23
- marta_confirm_mark = true;
24
- marta_result = "3";
28
+ document.marta_confirm_mark = true;
29
+ document.marta_result = "3";
25
30
  };
26
31
 
27
- function marta_add_data() {
28
- marta_confirm_mark = false;
29
- document.getElementById("marta_main_title").innerHTML = old_marta_Data + " elements found for " + marta_what;
32
+ document.marta_add_data = function() {
33
+ document.marta_confirm_mark = false;
34
+ document.getElementById("marta_main_title").innerHTML = document.old_marta_Data + " elements found for " + document.marta_what;
30
35
  };
31
36
 
32
- function marta_hide() {
37
+ document.marta_hide = function() {
33
38
  var toHide = document.querySelector("[martaclass=marta_div]");
34
39
  if (toHide.getAttribute("martastyle")=="hidden"){
35
40
  toHide.setAttribute("martastyle", "none");
@@ -3,7 +3,7 @@
3
3
  <div martaclass=marta_smthing martastyle=header>
4
4
  <h2 id=marta_main_title martaclass=marta_smthing></h2>
5
5
  <div martastyle=icons_holder martaclass=marta_smthing>
6
- <input type=button martaclass=marta_smthing martastyle=icon_button id=marta_hide onclick=marta_hide(); value=&#x21E8; />
6
+ <input type=button martaclass=marta_smthing martastyle=icon_button id=marta_hide value=&#x21E8; />
7
7
  </div>
8
8
  </div>
9
9
  <div martaclass=marta_smthing martastyle=hint>
@@ -19,9 +19,9 @@
19
19
  </div>
20
20
  <div id=marta_s_content martaclass=marta_smthing martastyle=main_content>
21
21
  <div martastyle=buttons_holder martaclass=marta_smthing>
22
- <input type=button martaclass=marta_smthing id=marta_confirm martastyle=confirm_button onclick=marta_end_loop(); value=Confirm />
23
- <input type=button martaclass=marta_smthing id=marta_set_by_hand martastyle=action_button onclick=marta_set_by_hand(); value="Set by hand" />
24
- <input type=button martaclass=marta_smthing id=marta_show_html martastyle=action_button onclick=marta_show_html(); value="Find in html" />
22
+ <input type=button martaclass=marta_smthing id=marta_confirm martastyle=confirm_button value=Confirm />
23
+ <input type=button martaclass=marta_smthing id=marta_set_by_hand martastyle=action_button value="Set by hand" />
24
+ <input type=button martaclass=marta_smthing id=marta_show_html martastyle=action_button value="Find in html" />
25
25
  </div>
26
26
  </div>
27
27
  <div id=marta_s_element_type martaclass=marta_smthing martastyle=options_holder>
@@ -1,113 +1,133 @@
1
- var marta_room = 0;
2
- var marta_result = {};
3
- var marta_confirm_mark = false;
4
- var marta_waits_iframe = "IFRAME";
1
+ document.marta_room = 0;
2
+ document.marta_result = {};
3
+ document.marta_confirm_mark = false;
4
+ document.marta_test_xx = 0;
5
+ document.marta_test_yy = 0;
5
6
 
6
- function sleep(ms) {
7
- ms += new Date().getTime();
8
- while (new Date() < ms){};
7
+ document.getElementById("marta_confirm").onclick = function() {document.marta_end_loop()};
8
+ document.getElementById("marta_set_by_hand").onclick = function() {document.marta_set_by_hand()};
9
+ document.getElementById("marta_show_html").onclick = function() {document.marta_show_html()};
10
+ document.getElementById("marta_hide").onclick = function() {document.marta_hide()};
11
+
12
+ document.marta_magic_click = function(e) {
13
+ if (document.marta_test_xx == 0) {var xx = e.clientX} else {var xx = document.marta_test_xx};
14
+ if (document.marta_test_yy == 0) {var yy = e.clientY} else {var yy = document.marta_test_yy};
15
+ document.getElementById("marta_magic_div").setAttribute("martastyle", "off");
16
+ document.marta_click_work(document.elementFromPoint(xx, yy));
17
+ document.getElementById("marta_magic_div").setAttribute("martastyle", "at_large");
9
18
  };
10
19
 
11
- var marta_monitor = setInterval(function(){
12
- var elem = document.activeElement;
13
- if(elem && elem.tagName == marta_waits_iframe){
14
- marta_waits_iframe = "Nope, she is not";
15
- marta_click_work(elem, true);
16
- } else {
17
- marta_waits_iframe = "IFRAME";
18
- };
19
- }, 100);
20
+ document.marta_create_element = function(dom, tag, attrs, inner) {
21
+ var element = document.createElement(tag);
22
+ dom.appendChild(element);
23
+ for (var key in attrs) {
24
+ element.setAttribute(key, attrs[key])
25
+ };
26
+ element.innerHTML = inner;
27
+ return element;
28
+ };
29
+
30
+ if (!document.getElementById("marta_magic_div")){
31
+ document.marta_create_element(document.body, "div", {"martaclass": "marta_smthing","id":"marta_magic_div", "martastyle": "at_large"}, "");
32
+ } else {
33
+ document.getElementById("marta_magic_div").setAttribute("martastyle", "at_large");
34
+ };
35
+ document.getElementById('marta_magic_div').onclick = function(e) {document.marta_magic_click(e)};
20
36
 
21
- function marta_add_field(title, what, key, marker) {
22
- marta_room++;
37
+ document.marta_add_field = function(title, what, key, marker) {
38
+ document.marta_room++;
23
39
  var objTo = document.getElementById("attr_fields");
24
40
  var divtest = document.createElement("div");
25
- var att = document.createAttribute("martaclass");
26
- att.value = "marta_smthing";
27
- divtest.setAttributeNode(att);
28
- divtest.innerHTML = "<div martaclass=marta_smthing class=label id=marta_title"+marta_room+">ATTR</div><div martaclass=marta_smthing martastyle=field_line class=content id=marta_staff"+marta_room+"><input martastyle=name_field martaclass=marta_smthing class=marta_s_name_field type=text disabled=disabled; id=marta_name"+marta_room+" value=><input onchange=marta_change_field(this); martastyle=value_field martaclass=marta_smthing type=text id=marta_default_value"+marta_room+" value=><input martastyle=cancel_button martaclass=marta_smthing type=button onclick=marta_delete_line("+marta_room+") value=Delete id=delete_marta_value"+marta_room+"</div>";
29
41
  objTo.appendChild(divtest);
30
- document.getElementById("marta_title"+marta_room ).innerHTML = title;
31
- document.getElementById("marta_name"+marta_room ).value = what;
32
- var field = document.getElementById("marta_default_value"+marta_room);
42
+ divtest.setAttribute("martaclass", "marta_smthing");
43
+ var headerDiv = document.marta_create_element(divtest, "div", {"martaclass": "marta_smthing", "class": "label", "id": "marta_title"+document.marta_room}, "ATTR");
44
+ var contentDiv = document.marta_create_element(divtest, "div", {"martaclass": "marta_smthing", "martastyle": "field_line", "class": "content", "id": "marta_staff"+document.marta_room}, "");
45
+ var nameField = document.marta_create_element(contentDiv, "input", {"martaclass": "marta_smthing", "martastyle": "name_field", "class": "marta_s_name_field", "type": "text", "disabled": "disabled;", "id": "marta_name"+document.marta_room, "value": ""}, "");
46
+ var valueField = document.marta_create_element(contentDiv, "input", {"martaclass": "marta_smthing", "martastyle": "value_field", "type": "text", "id": "marta_default_value"+document.marta_room, "value": ""}, "");
47
+ var cancelButton = document.marta_create_element(contentDiv, "input", {"martaclass": "marta_smthing", "martaroom": document.marta_room, "martastyle": "cancel_button", "type": "button", "id": "delete_marta_value"+document.marta_room, "value": "Delete"}, "");
48
+ document.getElementById("marta_title"+document.marta_room ).innerHTML = title;
49
+ document.getElementById("marta_name"+document.marta_room ).value = what;
50
+ var field = document.getElementById("marta_default_value"+document.marta_room);
33
51
  field.value = key;
34
52
  var att = document.createAttribute("marta_object_map");
35
53
  att.value = title+";;"+what+";;"+marker;
36
54
  field.setAttributeNode(att);
55
+ document.getElementById("delete_marta_value"+document.marta_room).onclick = function(e) {document.marta_delete_line(e)};
56
+ document.getElementById("marta_default_value"+document.marta_room).onchange = function(e) {document.marta_change_field(e)};
37
57
  };
38
58
 
39
- function marta_change_field(field){
59
+ document.marta_change_field = function(field){
40
60
  var data = field.getAttribute("marta_object_map").split(";;");
41
61
  if (data[2] == "-1"){
42
62
  if (field.value == ""){
43
- delete marta_result[data[0]][data[1]];
63
+ delete document.marta_result[data[0]][data[1]];
44
64
  } else {
45
- marta_result[data[0]][data[1]]=field.value;
65
+ document.marta_result[data[0]][data[1]]=field.value;
46
66
  };
47
67
  }else if (data[2] == "taggy"){
48
68
  if (field.value == ""){
49
- marta_result["options"][data[1]] = "*";
69
+ document.marta_result["options"][data[1]] = "*";
50
70
  } else {
51
- marta_result["options"][data[1]]=field.value;
71
+ document.marta_result["options"][data[1]]=field.value;
52
72
  };
53
73
  }else {
54
74
  if (field.value == ""){
55
- delete marta_result[data[0]][data[1]][parseInt(data[2])];
75
+ delete document.marta_result[data[0]][data[1]][parseInt(data[2])];
56
76
  } else {
57
- marta_result[data[0]][data[1]][parseInt(data[2])]=field.value;
77
+ document.marta_result[data[0]][data[1]][parseInt(data[2])]=field.value;
58
78
  };
59
79
  };
60
- marta_confirm();
80
+ document.marta_confirm();
61
81
  };
62
82
 
63
- function marta_clean_up(){
83
+ document.marta_clean_up = function(){
64
84
  var toClear = document.body.querySelectorAll("[martaclass=marta_div],[martaclass=marta_script],[martaclass=marta_style]");
65
85
  for (var i = 0; i < toClear.length; i++) {
66
86
  toClear[i].parentNode.removeChild(toClear[i]);
67
87
  };
68
- marta_room = 0;
88
+ document.marta_room = 0;
69
89
  };
70
90
 
71
- function marta_confirm(){
72
- if (marta_room != 0){
73
- marta_result["options"]["collection"] = document.getElementById("marta_array").checked;
74
- marta_clean_up();
75
- for (var what in marta_result){
76
- for (var key in marta_result[what]){
77
- if (marta_result[what][key] instanceof Array){
78
- for (var i = 0; i < marta_result[what][key].length; i++) {
79
- if (marta_result[what][key][i] == undefined) {
80
- marta_result[what][key].splice(i, 1);
91
+ document.marta_confirm = function(){
92
+ if (document.marta_room != 0){
93
+ document.marta_result["options"]["collection"] = document.getElementById("marta_array").checked;
94
+ document.marta_clean_up();
95
+ for (var what in document.marta_result){
96
+ for (var key in document.marta_result[what]){
97
+ if (document.marta_result[what][key] instanceof Array){
98
+ for (var i = 0; i < document.marta_result[what][key].length; i++) {
99
+ if (document.marta_result[what][key][i] == undefined) {
100
+ document.marta_result[what][key].splice(i, 1);
81
101
  i--;
82
102
  };
83
103
  };
84
104
  };
85
105
  };
86
106
  };
87
- marta_confirm_mark = true;
88
- return marta_result;
107
+ document.marta_confirm_mark = true;
108
+ return document.marta_result;
89
109
  };
90
110
  };
91
111
 
92
- function marta_add_data() {
93
- marta_result = old_marta_Data;
94
- marta_confirm_mark = false;
95
- document.getElementById("marta_main_title").innerHTML = marta_what;
96
- if (old_marta_Data != {}){
112
+ document.marta_add_data = function() {
113
+ document.marta_result = document.old_marta_Data;
114
+ document.marta_confirm_mark = false;
115
+ document.getElementById("marta_main_title").innerHTML = document.marta_what;
116
+ if (document.old_marta_Data != {}){
97
117
  try {
98
- document.getElementById("marta_array").checked = old_marta_Data["options"]["collection"];}
118
+ document.getElementById("marta_array").checked = document.old_marta_Data["options"]["collection"];}
99
119
  catch(e){};
100
- for (var what in old_marta_Data){
120
+ for (var what in document.old_marta_Data){
101
121
  if (what != "options"){
102
- marta_add_field("TAG", what, old_marta_Data["options"][what], "taggy");
103
- for (var key in old_marta_Data[what]){
122
+ document.marta_add_field("TAG", what, document.old_marta_Data["options"][what], "taggy");
123
+ for (var key in document.old_marta_Data[what]){
104
124
  if (/class/.test(key) == true){
105
- for (var k = 0, length = old_marta_Data[what][key].length; k < length; k++){
106
- marta_add_field(what, key, old_marta_Data[what][key][k], k);
125
+ for (var k = 0, length = document.old_marta_Data[what][key].length; k < length; k++){
126
+ document.marta_add_field(what, key, document.old_marta_Data[what][key][k], k);
107
127
  };
108
128
  }else
109
129
  {
110
- marta_add_field(what, key, old_marta_Data[what][key], "-1");
130
+ document.marta_add_field(what, key, document.old_marta_Data[what][key], "-1");
111
131
  };
112
132
  };
113
133
  };
@@ -115,28 +135,28 @@ function marta_add_data() {
115
135
  };
116
136
  };
117
137
 
118
- function marta_show_html() {
138
+ document.marta_show_html = function() {
119
139
  var area = document.getElementById("marta_s_html_holder");
120
- area.innerHTML = spaninize(document.documentElement.innerHTML);
140
+ area.innerHTML = document.spaninize(document.documentElement.innerHTML);
121
141
  };
122
142
 
123
- function marta_touch(element) {
143
+ document.marta_touch = function(element) {
124
144
  var control = element.textContent.replace(/</g,"&lt;").replace(/>/g,"&gt;");
125
145
  var everything = document.getElementsByTagName("*");
126
146
  for (var i=0, max=everything.length; i < max; i++) {
127
147
  var check = everything[i].outerHTML.replace(/</g,"&lt;").replace(/>/g,"&gt;");
128
148
  if (check == control) {
129
- everything[i].click();
149
+ document.marta_click_work(everything[i]);
130
150
  };
131
151
  };
132
152
  };
133
153
 
134
- function wrap(el, wrapper) {
154
+ document.wrap = function(el, wrapper) {
135
155
  wrapper.appendChild(el.cloneNode(true));
136
156
  el.parentNode.replaceChild(wrapper, el);
137
157
  };
138
158
 
139
- function spaninize(string) {
159
+ document.spaninize = function(string) {
140
160
  var dummy = document.createElement( "marta_span" );
141
161
  dummy.innerHTML = string;
142
162
  ignore = dummy.querySelectorAll("[martaclass=marta_div],[martaclass=marta_script],[martaclass=marta_style]");
@@ -154,104 +174,101 @@ function spaninize(string) {
154
174
  };
155
175
  var wrapper = document.createElement( "marta_span" );
156
176
  wrapper.setAttribute("martaclass","marta_smthing");
157
- wrapper.setAttribute("onclick","marta_touch(this);");
158
- wrap(everything[i], wrapper);
177
+ document.wrap(everything[i], wrapper);
159
178
  };
179
+ var theParent = document.getElementById("marta_s_html_holder");
180
+ theParent.onclick = function(e) {document.pretouch(e)};
160
181
  return dummy.innerHTML.replace(/<(?!.?marta_span)([^>]*)>/g,"&lt;$1&gt;").replace(/marta_span/g,"span");
161
182
  };
162
183
 
163
- function marta_click_work(e, iframe=false) {
164
- if (iframe == false){
165
- e = e || window.event;
166
- var target = e.target || e.srcElement;
167
- } else {
168
- target = e;
169
- };
184
+ document.pretouch = function(e) {
185
+ if (e.target !== e.currentTarget) {
186
+ var clickedItem = e.target;
187
+ document.marta_touch(clickedItem);
188
+ };
189
+ };
190
+
191
+ document.marta_click_work = function(target) {
170
192
  var marta_smthing = target.getAttribute("martaclass")=="marta_smthing";
171
193
  if(!marta_smthing){
172
194
  document.getElementById("attr_fields").innerHTML="";
173
- marta_room = 0;
174
- marta_result = {};
175
- marta_result["options"] = {};
176
- marta_after_click(target,"self");
195
+ document.marta_room = 0;
196
+ document.marta_result = {};
197
+ document.marta_result["options"] = {};
198
+ document.marta_after_click(target,"self");
177
199
  if (!!target.parentElement){
178
- marta_after_click(target.parentElement,"pappy");
200
+ document.marta_after_click(target.parentElement,"pappy");
179
201
  };
180
202
  if (!!target.parentElement.parentElement){
181
- marta_after_click(target.parentElement.parentElement,"granny");
182
- };
183
- if(!marta_confirm_mark){
184
- e.stopPropagation();
185
- e.preventDefault();
203
+ document.marta_after_click(target.parentElement.parentElement,"granny");
186
204
  };
187
- marta_confirm();
205
+ document.marta_confirm();
188
206
  };
189
207
  };
190
208
 
191
- document.onclick = function(e) {marta_click_work(e)};
192
-
193
- function marta_after_click(el, what) {
194
- marta_result[what] = {};
195
- marta_result["options"][what] = el.tagName;
196
- marta_add_field("TAG", what, marta_result["options"][what], "taggy");
209
+ document.marta_after_click = function(el, what) {
210
+ document.marta_result[what] = {};
211
+ document.marta_result["options"][what] = el.tagName;
212
+ document.marta_add_field("TAG", what, document.marta_result["options"][what], "taggy");
197
213
  for (var att, i = 0, atts = el.attributes, n = atts.length; i < n; i++){
198
214
  att = atts[i];
199
215
  if(/^[a-zA-Z0-9- _!@#$%^*();:,.?/]*$/.test(att.nodeValue) == true && att.nodeName != "martaclass"){
200
216
  if (/class/.test(att.nodeName) == true){
201
217
  var values=att.nodeValue.split(" ");
202
- marta_result[what][att.nodeName]=[];
218
+ document.marta_result[what][att.nodeName]=[];
203
219
  for (var val, j = 0, vals = values, l = vals.length; j < l; j++){
204
220
  val = vals[j];
205
- marta_result[what][att.nodeName][j]=val;
221
+ document.marta_result[what][att.nodeName][j]=val;
206
222
  };
207
223
  } else {
208
- marta_result[what][att.nodeName]=att.nodeValue;
224
+ document.marta_result[what][att.nodeName]=att.nodeValue;
209
225
  };
210
226
  };
211
227
  };
212
228
  if (what == "self"){
213
229
  try{
214
- marta_result[what]["retrieved_by_marta_text"]=el.firstChild.nodeValue;
230
+ document.marta_result[what]["retrieved_by_marta_text"]=el.firstChild.nodeValue;
215
231
  }catch(e){};
216
232
  };
217
- for (var key in marta_result[what]){
233
+ for (var key in document.marta_result[what]){
218
234
  if (/class/.test(key) == true){
219
- for (var k = 0, length = marta_result[what][key].length; k < length; k++){
220
- marta_add_field(what, key, marta_result[what][key][k], k);
235
+ for (var k = 0, length = document.marta_result[what][key].length; k < length; k++){
236
+ document.marta_add_field(what, key, document.marta_result[what][key][k], k);
221
237
  };
222
238
  }else
223
239
  {
224
- marta_add_field(what, key, marta_result[what][key], "-1");
240
+ document.marta_add_field(what, key, document.marta_result[what][key], "-1");
225
241
  };
226
242
  };
227
243
  };
228
244
 
229
- function marta_delete_line(line) {
245
+ document.marta_delete_line = function(theEvent) {
246
+ var line = theEvent.target.getAttribute("martaroom");
230
247
  var title = document.getElementById("marta_title"+line);
231
248
  var staff = document.getElementById("marta_staff"+line);
232
249
  var field = document.getElementById("marta_default_value"+line);
233
250
  field.value = "";
234
- marta_change_field(field);
251
+ document.marta_change_field(field);
235
252
  staff.parentNode.removeChild(staff);
236
253
  title.parentNode.removeChild(title);
237
254
  };
238
255
 
239
- function marta_set_by_hand(){
256
+ document.marta_set_by_hand = function(){
240
257
  var toClear = document.querySelector("[martaclass=marta_div]");
241
258
  toClear.parentNode.removeChild(toClear);
242
- marta_confirm_mark = true;
243
- marta_result = "3";
259
+ document.marta_confirm_mark = true;
260
+ document.marta_result = "3";
244
261
  };
245
262
 
246
- function marta_end_loop(){
247
- if (marta_room != 0){
248
- marta_clean_up();
249
- marta_confirm_mark = true;
250
- marta_result = "1";
263
+ document.marta_end_loop = function(){
264
+ if (document.marta_room != 0){
265
+ document.marta_clean_up();
266
+ document.marta_confirm_mark = true;
267
+ document.marta_result = "1";
251
268
  }
252
269
  };
253
270
 
254
- function marta_hide() {
271
+ document.marta_hide = function() {
255
272
  var toHide = document.querySelector("[martaclass=marta_div]");
256
273
  if (toHide.getAttribute("martastyle")=="hidden"){
257
274
  toHide.setAttribute("martastyle", "none");
@@ -1,8 +1,8 @@
1
- function marta_add_data(){
2
- document.getElementById("title").innerHTML = marta_what;
3
- document.getElementById(old_marta_Data).innerHTML = old_marta_Data;
1
+ document.marta_add_data = function(){
2
+ document.getElementById("title").innerHTML = document.marta_what;
3
+ document.getElementById(document.old_marta_Data).innerHTML = document.old_marta_Data;
4
4
  };
5
- var marta_result = "";
6
- var marta_confirm_mark = false;
7
- setTimeout(function() { marta_result = "Done" }, 1000);
8
- setTimeout(function() { marta_confirm_mark = true }, 2000);
5
+ document.marta_result = "";
6
+ document.marta_confirm_mark = false;
7
+ setTimeout(function() { document.marta_result = "Done" }, 1000);
8
+ setTimeout(function() { document.marta_confirm_mark = true }, 2000);
@@ -3,7 +3,7 @@
3
3
  <div martaclass=marta_smthing martastyle=header>
4
4
  <h2 martaclass=marta_smthing id=marta_main_title></h2>
5
5
  <div martaclass=marta_smthing martastyle=icons_holder>
6
- <input type=button martaclass=marta_smthing martastyle=icon_button id=marta_hide onclick=marta_hide(); value=&#x21E8; />
6
+ <input type=button martaclass=marta_smthing martastyle=icon_button id=marta_hide value=&#x21E8; />
7
7
  </div>
8
8
  </div>
9
9
  <div martaclass=marta_smthing martastyle=hint>
@@ -1,41 +1,61 @@
1
- var marta_room = 0;
2
- var marta_result = {};
3
- var marta_confirm_mark = false;
1
+ document.marta_room = 0;
2
+ document.marta_result = {};
3
+ document.marta_confirm_mark = false;
4
4
 
5
- function marta_add_field() {
6
- marta_room++;
5
+ document.getElementById("marta_confirm").onclick = function() {document.marta_confirm()};
6
+ document.getElementById("marta_more_fields").onclick = function() {document.marta_add_field()};
7
+ document.getElementById("marta_hide").onclick = function() {document.marta_hide()};
8
+
9
+ document.marta_create_element = function(dom, tag, attrs, inner) {
10
+ var element = document.createElement(tag);
11
+ dom.appendChild(element);
12
+ for (var key in attrs) {
13
+ element.setAttribute(key, attrs[key])
14
+ };
15
+ element.innerHTML = inner;
16
+ return element;
17
+ };
18
+
19
+ document.marta_add_field = function() {
20
+ document.marta_room++;
7
21
  var objTo = document.getElementById("vars_fileds");
8
22
  var divtest = document.createElement("div");
9
- divtest.innerHTML = "<div martastyle=field_line id=marta_staff"+marta_room+"><input type=text martaclass=marta_smthing martastyle=name_field id=marta_name"+marta_room+" value=><input martaclass=marta_smthing martastyle=value_field type=text id=marta_default_value"+marta_room+" value=><input martaclass=marta_smthing martastyle=cancel_button type=button onclick=marta_delete_line("+marta_room+") value=Delete id=delete_marta_value"+marta_room+"</div>";
10
23
  objTo.appendChild(divtest);
24
+ var contentDiv = document.marta_create_element(divtest, "div", {"martaclass": "marta_smthing", "martastyle": "field_line", "class": "content", "id": "marta_staff"+document.marta_room}, "");
25
+ var nameField = document.marta_create_element(contentDiv, "input", {"martaclass": "marta_smthing", "martastyle": "name_field", "class": "marta_s_name_field", "type": "text", "id": "marta_name"+document.marta_room, "value": ""}, "");
26
+ var valueField = document.marta_create_element(contentDiv, "input", {"martaclass": "marta_smthing", "martastyle": "value_field", "type": "text", "id": "marta_default_value"+document.marta_room, "value": ""}, "");
27
+ var cancelButton = document.marta_create_element(contentDiv, "input", {"martaclass": "marta_smthing", "martaroom": document.marta_room, "martastyle": "cancel_button", "type": "button", "id": "delete_marta_value"+document.marta_room, "value": "Delete"}, "");
28
+ document.getElementById("delete_marta_value"+document.marta_room).onclick = function(e) {document.marta_delete_line(e)};
11
29
  };
12
- function marta_confirm(){
13
- for(i=1; i<=marta_room; i++){
30
+
31
+ document.marta_confirm = function(){
32
+ for(i=1; i<=document.marta_room; i++){
14
33
  if (!!document.getElementById("marta_name"+i) && (document.getElementById("marta_name"+i).value != "")) {
15
- marta_result[document.getElementById("marta_name"+i).value] = document.getElementById("marta_default_value"+i).value;
34
+ document.marta_result[document.getElementById("marta_name"+i).value] = document.getElementById("marta_default_value"+i).value;
16
35
  };
17
36
  };
18
37
  var toClear = document.querySelector("[martaclass=marta_div]");
19
38
  toClear.parentNode.removeChild(toClear);
20
- marta_confirm_mark = true;
21
- return marta_result;};
39
+ document.marta_confirm_mark = true;
40
+ return document.marta_result;};
22
41
 
23
- function marta_add_data() {
24
- document.getElementById("marta_main_title").innerHTML = "You are defining " + marta_what;
25
- for (var key in old_marta_Data){
26
- marta_add_field();
27
- document.getElementById("marta_name"+marta_room ).value = key;
28
- document.getElementById("marta_default_value"+marta_room ).value = old_marta_Data[key];
42
+ document.marta_add_data = function() {
43
+ document.getElementById("marta_main_title").innerHTML = "You are defining " + document.marta_what;
44
+ for (var key in document.old_marta_Data){
45
+ document.marta_add_field();
46
+ document.getElementById("marta_name"+document.marta_room ).value = key;
47
+ document.getElementById("marta_default_value"+document.marta_room ).value = document.old_marta_Data[key];
29
48
  };
30
49
  };
31
50
 
32
- function marta_delete_line(line) {
51
+ document.marta_delete_line = function(theEvent) {
52
+ var line = theEvent.target.getAttribute("martaroom");
33
53
  var staff = document.getElementById("marta_staff"+line);
34
54
  title.parentNode.removeChild(title);
35
55
  staff.parentNode.removeChild(staff);
36
56
  };
37
57
 
38
- function marta_hide() {
58
+ document.marta_hide = function() {
39
59
  var toHide = document.querySelector("[martaclass=marta_div]");
40
60
  if (toHide.getAttribute("martastyle")=="hidden"){
41
61
  toHide.setAttribute("martastyle", "none");
@@ -111,7 +111,7 @@ div[martaclass=marta_div] * {
111
111
  outline-color : invert;
112
112
  outline-style : none;
113
113
  outline-width : medium;
114
- overflow : visible;
114
+ overflow : auto;
115
115
  overflow-x : visible;
116
116
  overflow-y : visible;
117
117
  padding : 0;
@@ -127,7 +127,7 @@ div[martaclass=marta_div] * {
127
127
  right : auto;
128
128
  tab-size : 8;
129
129
  table-layout : auto;
130
- text-align : inherit;
130
+ text-align : auto;
131
131
  text-align-last : auto;
132
132
  text-decoration : none;
133
133
  text-decoration-color : inherit;
@@ -213,6 +213,26 @@ div[martastyle=hint] {
213
213
  margin: 0 auto;
214
214
  }
215
215
 
216
+ div[martastyle=at_large] {
217
+ position:fixed;
218
+ padding:0;
219
+ margin:0;
220
+ top:0;
221
+ left:0;
222
+ opacity: 0;
223
+ background: black;
224
+ height: 100%;
225
+ width: 100%;
226
+ pointer-events: visible;
227
+ display: block;
228
+ z-index: 149000;
229
+ }
230
+
231
+ div[martastyle=off] {
232
+ height: 0%;
233
+ width: 0%;
234
+ }
235
+
216
236
  div[martastyle=html_content]{
217
237
  text-align: center;
218
238
  }
@@ -28,7 +28,7 @@ module Marta
28
28
  @custom_scripts = custom_scripts
29
29
  @default_vars = [{"marta_what": "\"#{@title}\""},
30
30
  {"old_marta_Data": @data.to_s.gsub('=>',':').gsub('nil','null')}]
31
- @default_scripts = ["marta_add_data();"]
31
+ @default_scripts = ["document.marta_add_data();"]
32
32
  end
33
33
 
34
34
  # "first" or "last".
@@ -39,12 +39,16 @@ module Marta
39
39
  # Inserting to the page
40
40
  def insert_to_page(tag, inner, first = true)
41
41
  where = get_where(first)
42
- script = <<-JS
43
- var newMartaObject = document.createElement('#{tag}');
44
- newMartaObject.setAttribute('martaclass','marta_#{tag}');
45
- newMartaObject.innerHTML = '#{inner}';
46
- document.body.insertBefore(newMartaObject,document.body.#{where}Child);
47
- JS
42
+ if tag != "script"
43
+ script = <<-JS
44
+ var newMartaObject = document.createElement('#{tag}');
45
+ newMartaObject.setAttribute('martaclass','marta_#{tag}');
46
+ newMartaObject.innerHTML = '#{inner}';
47
+ document.body.insertBefore(newMartaObject,document.body.#{where}Child);
48
+ JS
49
+ else
50
+ script = inner
51
+ end
48
52
  @engine.execute_script script.gsub("\n",'')
49
53
  end
50
54
 
@@ -72,7 +76,7 @@ module Marta
72
76
 
73
77
  # Syringe sets javascript variables
74
78
  def set_var(var, value)
75
- insert_to_page('script', "var #{var} = #{value};", false)
79
+ insert_to_page('script', "document.#{var} = #{value};", false)
76
80
  end
77
81
 
78
82
  # Syringe runs scripts
@@ -111,13 +115,10 @@ module Marta
111
115
  result = false
112
116
  while result != true
113
117
  # When Marta can't get a result she is reinjecting her stuff
114
- begin
115
- result = @engine.execute_script("return marta_confirm_mark")
116
- rescue
117
- actual_injection
118
- end
118
+ result = @engine.execute_script("return document.marta_confirm_mark")
119
+ actual_injection if result.nil?
119
120
  end
120
- @engine.execute_script("return marta_result")
121
+ @engine.execute_script("return document.marta_result")
121
122
  end
122
123
  end
123
124
 
@@ -18,6 +18,7 @@ module Marta
18
18
  @@learn = Hash.new
19
19
  @@engine = Hash.new
20
20
  @@base_url = Hash.new
21
+ @@cold_timeout = Hash.new
21
22
 
22
23
  # Getting uniq id for process thread
23
24
  def self.thread_id
@@ -58,6 +59,11 @@ module Marta
58
59
  @@base_url[thread_id]
59
60
  end
60
61
 
62
+ # Time setting for Marta. She will wait that time before active search
63
+ def self.cold_timeout
64
+ @@cold_timeout[thread_id]
65
+ end
66
+
61
67
  # Marta is changing parameters by the same scheme.
62
68
  def self.parameter_set(what, value, default)
63
69
  what[thread_id] = !value.nil? ? value : what[thread_id]
@@ -85,6 +91,9 @@ module Marta
85
91
 
86
92
  # Marta is setting engine by pretty comlex rules
87
93
  def self.set_engine(value)
94
+ if (engine.class == Watir::Browser) and (value.class == Watir::Browser)
95
+ engine.close
96
+ end
88
97
  iframe_locate
89
98
  @@engine = parameter_set(@@engine, value, nil)
90
99
  iframe_switch_to
@@ -108,15 +117,24 @@ module Marta
108
117
  @@tolerancy = parameter_set(@@tolerancy, value, 1024)
109
118
  end
110
119
 
111
- # Marta uses a simple ruke to set the basic url.
112
- def self.set_base_url(value)
113
- if (value.nil?) or (value.class == String)
114
- @@base_url = parameter_set(@@base_url, value, "")
120
+ def self.parameter_check_and_set(where, value, default, expected_class)
121
+ if (value.nil?) or (value.class == expected_class)
122
+ where = parameter_set(where, value, default)
115
123
  else
116
- raise ArgumentError, "Basic url at least should be a string. Not"\
117
- " a #{value}:#{value.class}"
124
+ raise ArgumentError, "The value should be a #{expected_class}."\
125
+ " Not a #{value}:#{value.class}"
118
126
  end
119
127
  end
128
+
129
+ # Marta uses a simple rule to set the basic url.
130
+ def self.set_base_url(value)
131
+ parameter_check_and_set(@@base_url, value, "", String)
132
+ end
133
+
134
+ # Marta uses simple rule to set the cold timeout
135
+ def self.set_cold_timeout(value)
136
+ parameter_check_and_set(@@cold_timeout, value, 10, Fixnum)
137
+ end
120
138
  end
121
139
 
122
140
  private
@@ -147,5 +165,9 @@ module Marta
147
165
  def base_url
148
166
  SettingMaster.base_url
149
167
  end
168
+
169
+ def cold_timeout
170
+ SettingMaster.cold_timeout
171
+ end
150
172
  end
151
173
  end
data/lib/marta/version.rb CHANGED
@@ -1,4 +1,4 @@
1
1
  module Marta
2
- VERSION = "0.31813"
2
+ VERSION = "0.31831"
3
3
  NAME = "marta"
4
4
  end
data/lib/marta.rb CHANGED
@@ -61,13 +61,14 @@ module Marta
61
61
  # Settings can be changed at any time by calling dance with.
62
62
  # Read more in the README
63
63
  def dance_with(browser: nil, folder: nil, learn: nil, tolerancy: nil,
64
- base_url: nil)
64
+ base_url: nil, cold_timeout: nil)
65
65
  SettingMaster.set_engine browser
66
66
  SettingMaster.set_folder folder
67
67
  SettingMaster.set_base_url base_url
68
68
  SettingMaster.set_learn learn
69
69
  read_folder
70
70
  SettingMaster.set_tolerancy tolerancy
71
+ SettingMaster.set_cold_timeout cold_timeout
71
72
  engine
72
73
  end
73
74
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: marta
3
3
  version: !ruby/object:Gem::Version
4
- version: '0.31813'
4
+ version: '0.31831'
5
5
  platform: ruby
6
6
  authors:
7
7
  - Sergei Seleznev
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2017-09-01 00:00:00.000000000 Z
11
+ date: 2017-09-10 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler