kopia lustrzana https://github.com/dgtlmoon/changedetection.io
				
				
				
			UI - Ability to select between any difference date ( from / to ) and minor UI cleanup for differences page (#1855)
							rodzic
							
								
									3e2b55a46f
								
							
						
					
					
						commit
						da421fe110
					
				|  | @ -912,21 +912,29 @@ def changedetection_app(config=None, datastore_o=None): | |||
| 
 | ||||
|         # Read as binary and force decode as UTF-8 | ||||
|         # Windows may fail decode in python if we just use 'r' mode (chardet decode exception) | ||||
|         try: | ||||
|             newest_version_file_contents = watch.get_history_snapshot(dates[-1]) | ||||
|         except Exception as e: | ||||
|             newest_version_file_contents = "Unable to read {}.\n".format(dates[-1]) | ||||
| 
 | ||||
|         previous_version = request.args.get('previous_version') | ||||
|         previous_timestamp = dates[-2] | ||||
|         if previous_version: | ||||
|             previous_timestamp = previous_version | ||||
|         from_version = request.args.get('from_version') | ||||
|         from_version_index = -2 # second newest | ||||
|         if from_version and from_version in dates: | ||||
|             from_version_index = dates.index(from_version) | ||||
|         else: | ||||
|             from_version = dates[from_version_index] | ||||
| 
 | ||||
|         try: | ||||
|             previous_version_file_contents = watch.get_history_snapshot(previous_timestamp) | ||||
|             from_version_file_contents = watch.get_history_snapshot(dates[from_version_index]) | ||||
|         except Exception as e: | ||||
|             previous_version_file_contents = "Unable to read {}.\n".format(previous_timestamp) | ||||
|             from_version_file_contents = "Unable to read to-version at index{}.\n".format(dates[from_version_index]) | ||||
| 
 | ||||
|         to_version = request.args.get('to_version') | ||||
|         to_version_index = -1 | ||||
|         if to_version and to_version in dates: | ||||
|             to_version_index = dates.index(to_version) | ||||
|         else: | ||||
|             to_version = dates[to_version_index] | ||||
| 
 | ||||
|         try: | ||||
|             to_version_file_contents = watch.get_history_snapshot(dates[to_version_index]) | ||||
|         except Exception as e: | ||||
|             to_version_file_contents = "Unable to read to-version at index{}.\n".format(dates[to_version_index]) | ||||
| 
 | ||||
|         screenshot_url = watch.get_screenshot() | ||||
| 
 | ||||
|  | @ -942,7 +950,8 @@ def changedetection_app(config=None, datastore_o=None): | |||
| 
 | ||||
|         output = render_template("diff.html", | ||||
|                                  current_diff_url=watch['url'], | ||||
|                                  current_previous_version=str(previous_version), | ||||
|                                  from_version=str(from_version), | ||||
|                                  to_version=str(to_version), | ||||
|                                  extra_stylesheets=extra_stylesheets, | ||||
|                                  extra_title=" - Diff - {}".format(watch['title'] if watch['title'] else watch['url']), | ||||
|                                  extract_form=extract_form, | ||||
|  | @ -951,13 +960,14 @@ def changedetection_app(config=None, datastore_o=None): | |||
|                                  last_error_screenshot=watch.get_error_snapshot(), | ||||
|                                  last_error_text=watch.get_error_text(), | ||||
|                                  left_sticky=True, | ||||
|                                  newest=newest_version_file_contents, | ||||
|                                  newest=to_version_file_contents, | ||||
|                                  newest_version_timestamp=dates[-1], | ||||
|                                  password_enabled_and_share_is_off=password_enabled_and_share_is_off, | ||||
|                                  previous=previous_version_file_contents, | ||||
|                                  from_version_file_contents=from_version_file_contents, | ||||
|                                  to_version_file_contents=to_version_file_contents, | ||||
|                                  screenshot=screenshot_url, | ||||
|                                  uuid=uuid, | ||||
|                                  versions=dates[:-1], # All except current/last | ||||
|                                  versions=dates, # All except current/last | ||||
|                                  watch_a=watch | ||||
|                                  ) | ||||
| 
 | ||||
|  |  | |||
|  | @ -1,110 +1,105 @@ | |||
| var a = document.getElementById("a"); | ||||
| var b = document.getElementById("b"); | ||||
| var result = document.getElementById("result"); | ||||
| 
 | ||||
| function changed() { | ||||
|   // https://github.com/kpdecker/jsdiff/issues/389
 | ||||
|   // I would love to use `{ignoreWhitespace: true}` here but it breaks the formatting
 | ||||
|   options = { | ||||
|     ignoreWhitespace: document.getElementById("ignoreWhitespace").checked, | ||||
|   }; | ||||
| 
 | ||||
|   var diff = Diff[window.diffType](a.textContent, b.textContent, options); | ||||
|   var fragment = document.createDocumentFragment(); | ||||
|   for (var i = 0; i < diff.length; i++) { | ||||
|     if (diff[i].added && diff[i + 1] && diff[i + 1].removed) { | ||||
|       var swap = diff[i]; | ||||
|       diff[i] = diff[i + 1]; | ||||
|       diff[i + 1] = swap; | ||||
|     } | ||||
| 
 | ||||
|     var node; | ||||
|     if (diff[i].removed) { | ||||
|       node = document.createElement("del"); | ||||
|       node.classList.add("change"); | ||||
|       const wrapper = node.appendChild(document.createElement("span")); | ||||
|       wrapper.appendChild(document.createTextNode(diff[i].value)); | ||||
|     } else if (diff[i].added) { | ||||
|       node = document.createElement("ins"); | ||||
|       node.classList.add("change"); | ||||
|       const wrapper = node.appendChild(document.createElement("span")); | ||||
|       wrapper.appendChild(document.createTextNode(diff[i].value)); | ||||
|     } else { | ||||
|       node = document.createTextNode(diff[i].value); | ||||
|     } | ||||
|     fragment.appendChild(node); | ||||
|   } | ||||
| 
 | ||||
|   result.textContent = ""; | ||||
|   result.appendChild(fragment); | ||||
| 
 | ||||
|   // Jump at start
 | ||||
|   inputs.current = 0; | ||||
|   next_diff(); | ||||
| } | ||||
| 
 | ||||
| window.onload = function () { | ||||
|   /* Convert what is options from UTC time.time() to local browser time */ | ||||
|   var diffList = document.getElementById("diff-version"); | ||||
|   if (typeof diffList != "undefined" && diffList != null) { | ||||
|     for (var option of diffList.options) { | ||||
|       var dateObject = new Date(option.value * 1000); | ||||
|       option.label = dateObject.toLocaleString(); | ||||
|     } | ||||
|   } | ||||
| 
 | ||||
|   /* Set current version date as local time in the browser also */ | ||||
|   var current_v = document.getElementById("current-v-date"); | ||||
|   var dateObject = new Date(newest_version_timestamp * 1000); | ||||
|   current_v.innerHTML = dateObject.toLocaleString(); | ||||
|   onDiffTypeChange( | ||||
|     document.querySelector('#settings [name="diff_type"]:checked'), | ||||
|   ); | ||||
|   changed(); | ||||
| }; | ||||
| 
 | ||||
| a.onpaste = a.onchange = b.onpaste = b.onchange = changed; | ||||
| 
 | ||||
| if ("oninput" in a) { | ||||
|   a.oninput = b.oninput = changed; | ||||
| } else { | ||||
|   a.onkeyup = b.onkeyup = changed; | ||||
| } | ||||
| 
 | ||||
| function onDiffTypeChange(radio) { | ||||
|   window.diffType = radio.value; | ||||
|   // Not necessary
 | ||||
|   //	document.title = "Diff " + radio.value.slice(4);
 | ||||
| } | ||||
| 
 | ||||
| var radio = document.getElementsByName("diff_type"); | ||||
| for (var i = 0; i < radio.length; i++) { | ||||
|   radio[i].onchange = function (e) { | ||||
|     onDiffTypeChange(e.target); | ||||
|     changed(); | ||||
|   }; | ||||
| } | ||||
| 
 | ||||
| document.getElementById("ignoreWhitespace").onchange = function (e) { | ||||
|   changed(); | ||||
| }; | ||||
| 
 | ||||
| var inputs = document.getElementsByClassName("change"); | ||||
| inputs.current = 0; | ||||
| 
 | ||||
| function next_diff() { | ||||
|   var element = inputs[inputs.current]; | ||||
|   var headerOffset = 80; | ||||
|   var elementPosition = element.getBoundingClientRect().top; | ||||
|   var offsetPosition = elementPosition - headerOffset + window.scrollY; | ||||
| 
 | ||||
|   window.scrollTo({ | ||||
|     top: offsetPosition, | ||||
|     behavior: "smooth", | ||||
|   }); | ||||
| 
 | ||||
|   inputs.current++; | ||||
|   if (inputs.current >= inputs.length) { | ||||
| $(document).ready(function () { | ||||
|     var a = document.getElementById("a"); | ||||
|     var b = document.getElementById("b"); | ||||
|     var result = document.getElementById("result"); | ||||
|     var inputs = document.getElementsByClassName("change"); | ||||
|     inputs.current = 0; | ||||
|   } | ||||
| } | ||||
| 
 | ||||
|     function changed() { | ||||
|         // https://github.com/kpdecker/jsdiff/issues/389
 | ||||
|         // I would love to use `{ignoreWhitespace: true}` here but it breaks the formatting
 | ||||
|         options = { | ||||
|             ignoreWhitespace: document.getElementById("ignoreWhitespace").checked, | ||||
|         }; | ||||
| 
 | ||||
|         var diff = Diff[window.diffType](a.textContent, b.textContent, options); | ||||
|         var fragment = document.createDocumentFragment(); | ||||
|         for (var i = 0; i < diff.length; i++) { | ||||
|             if (diff[i].added && diff[i + 1] && diff[i + 1].removed) { | ||||
|                 var swap = diff[i]; | ||||
|                 diff[i] = diff[i + 1]; | ||||
|                 diff[i + 1] = swap; | ||||
|             } | ||||
| 
 | ||||
|             var node; | ||||
|             if (diff[i].removed) { | ||||
|                 node = document.createElement("del"); | ||||
|                 node.classList.add("change"); | ||||
|                 const wrapper = node.appendChild(document.createElement("span")); | ||||
|                 wrapper.appendChild(document.createTextNode(diff[i].value)); | ||||
|             } else if (diff[i].added) { | ||||
|                 node = document.createElement("ins"); | ||||
|                 node.classList.add("change"); | ||||
|                 const wrapper = node.appendChild(document.createElement("span")); | ||||
|                 wrapper.appendChild(document.createTextNode(diff[i].value)); | ||||
|             } else { | ||||
|                 node = document.createTextNode(diff[i].value); | ||||
|             } | ||||
|             fragment.appendChild(node); | ||||
|         } | ||||
| 
 | ||||
|         result.textContent = ""; | ||||
|         result.appendChild(fragment); | ||||
| 
 | ||||
|         // Jump at start
 | ||||
|         inputs.current = 0; | ||||
|         next_diff(); | ||||
|     } | ||||
| 
 | ||||
|     $('.needs-localtime').each(function () { | ||||
|         for (var option of this.options) { | ||||
|             var dateObject = new Date(option.value * 1000); | ||||
|             option.label = dateObject.toLocaleString(undefined, {dateStyle: "full", timeStyle: "medium"}); | ||||
|         } | ||||
|     }) | ||||
|     onDiffTypeChange( | ||||
|         document.querySelector('#settings [name="diff_type"]:checked'), | ||||
|     ); | ||||
|     changed(); | ||||
| 
 | ||||
|     a.onpaste = a.onchange = b.onpaste = b.onchange = changed; | ||||
| 
 | ||||
|     if ("oninput" in a) { | ||||
|         a.oninput = b.oninput = changed; | ||||
|     } else { | ||||
|         a.onkeyup = b.onkeyup = changed; | ||||
|     } | ||||
| 
 | ||||
|     function onDiffTypeChange(radio) { | ||||
|         window.diffType = radio.value; | ||||
|         // Not necessary
 | ||||
|         //	document.title = "Diff " + radio.value.slice(4);
 | ||||
|     } | ||||
| 
 | ||||
|     var radio = document.getElementsByName("diff_type"); | ||||
|     for (var i = 0; i < radio.length; i++) { | ||||
|         radio[i].onchange = function (e) { | ||||
|             onDiffTypeChange(e.target); | ||||
|             changed(); | ||||
|         }; | ||||
|     } | ||||
| 
 | ||||
|     document.getElementById("ignoreWhitespace").onchange = function (e) { | ||||
|         changed(); | ||||
|     }; | ||||
| 
 | ||||
| 
 | ||||
|     function next_diff() { | ||||
|         var element = inputs[inputs.current]; | ||||
|         var headerOffset = 80; | ||||
|         var elementPosition = element.getBoundingClientRect().top; | ||||
|         var offsetPosition = elementPosition - headerOffset + window.scrollY; | ||||
| 
 | ||||
|         window.scrollTo({ | ||||
|             top: offsetPosition, | ||||
|             behavior: "smooth", | ||||
|         }); | ||||
| 
 | ||||
|         inputs.current++; | ||||
|         if (inputs.current >= inputs.length) { | ||||
|             inputs.current = 0; | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
| }); | ||||
| 
 | ||||
|  |  | |||
|  | @ -187,6 +187,10 @@ ins { | |||
|     padding: 0.5em; } | ||||
|   #settings ins { | ||||
|     padding: 0.5em; } | ||||
|   #settings option:checked { | ||||
|     font-weight: bold; } | ||||
|   #settings [type=radio], #settings [type=checkbox] { | ||||
|     vertical-align: middle; } | ||||
| 
 | ||||
| .source { | ||||
|   position: absolute; | ||||
|  |  | |||
|  | @ -77,6 +77,13 @@ ins { | |||
|   ins { | ||||
|     padding: 0.5em; | ||||
|   } | ||||
| 
 | ||||
|   option:checked { | ||||
|     font-weight: bold; | ||||
|   } | ||||
|   [type=radio],[type=checkbox] { | ||||
|     vertical-align: middle; | ||||
|   } | ||||
| } | ||||
| 
 | ||||
| .source { | ||||
|  |  | |||
|  | @ -13,10 +13,31 @@ | |||
| <script src="{{url_for('static_content', group='js', filename='diff-overview.js')}}" defer></script> | ||||
| 
 | ||||
| <div id="settings"> | ||||
|     <h1>Differences</h1> | ||||
|     <form class="pure-form " action="" method="GET"> | ||||
|         <fieldset> | ||||
| 
 | ||||
|             {% if versions|length >= 1 %} | ||||
|                 <strong>Compare</strong> | ||||
|                 <del class="change"><span>from</span></del> | ||||
|                 <select id="diff-version" name="from_version" class="needs-localtime"> | ||||
|                     {% for version in versions|reverse %} | ||||
|                         <option value="{{ version }}" {% if version== from_version %} selected="" {% endif %}> | ||||
|                             {{ version }} | ||||
|                         </option> | ||||
|                     {% endfor %} | ||||
|                 </select> | ||||
|                 <ins class="change"><span>to</span></ins> | ||||
|                 <select id="current-version" name="to_version" class="needs-localtime"> | ||||
|                     {% for version in versions|reverse %} | ||||
|                         <option value="{{ version }}" {% if version== to_version %} selected="" {% endif %}> | ||||
|                             {{ version }} | ||||
|                         </option> | ||||
|                     {% endfor %} | ||||
|                 </select> | ||||
|                 <button type="submit" class="pure-button pure-button-primary">Go</button> | ||||
|             {% endif %} | ||||
|         </fieldset> | ||||
|         <fieldset> | ||||
|             <strong>Style</strong> | ||||
|             <label for="diffWords" class="pure-checkbox"> | ||||
|                 <input type="radio" name="diff_type" id="diffWords" value="diffWords"> Words</label> | ||||
|             <label for="diffLines" class="pure-checkbox"> | ||||
|  | @ -26,28 +47,16 @@ | |||
|                 <input type="radio" name="diff_type" id="diffChars" value="diffChars"> Chars</label> | ||||
|             <!-- @todo - when mimetype is JSON, select this by default? --> | ||||
|             <label for="diffJson" class="pure-checkbox"> | ||||
|                 <input type="radio" name="diff_type" id="diffJson" value="diffJson" > JSON</label> | ||||
|                 <input type="radio" name="diff_type" id="diffJson" value="diffJson"> JSON</label> | ||||
| 
 | ||||
|             {% if versions|length >= 1 %} | ||||
|             <label for="diff-version">Compare newest (<span id="current-v-date"></span>) with</label> | ||||
|             <select id="diff-version" name="previous_version"> | ||||
|                 {% for version in versions|reverse %} | ||||
|                 <option value="{{version}}" {% if version== current_previous_version %} selected="" {% endif %}> | ||||
|                     {{version}} | ||||
|                 </option> | ||||
|                 {% endfor %} | ||||
|             </select> | ||||
|             <button type="submit" class="pure-button pure-button-primary">Go</button> | ||||
|             {% endif %} | ||||
|         </fieldset> | ||||
|     </form> | ||||
|     <del>Removed text</del> | ||||
|     <ins>Inserted Text</ins> | ||||
|     <span> | ||||
|             <span> | ||||
|         <!-- https://github.com/kpdecker/jsdiff/issues/389 ? --> | ||||
|         <label for="ignoreWhitespace" class="pure-checkbox" id="label-diff-ignorewhitespace"> | ||||
|             <input type="checkbox" id="ignoreWhitespace" name="ignoreWhitespace" > Ignore Whitespace</label> | ||||
|             <input type="checkbox" id="ignoreWhitespace" name="ignoreWhitespace"> Ignore Whitespace</label> | ||||
|     </span> | ||||
|         </fieldset> | ||||
|     </form> | ||||
| 
 | ||||
| </div> | ||||
| 
 | ||||
| <div id="diff-jump"> | ||||
|  | @ -91,8 +100,8 @@ | |||
|              <tbody> | ||||
|              <tr> | ||||
|                  <!-- just proof of concept copied straight from github.com/kpdecker/jsdiff --> | ||||
|                  <td id="a" style="display: none;">{{previous}}</td> | ||||
|                  <td id="b" style="display: none;">{{newest}}</td> | ||||
|                  <td id="a" style="display: none;">{{from_version_file_contents}}</td> | ||||
|                  <td id="b" style="display: none;">{{to_version_file_contents}}</td> | ||||
|                  <td id="diff-col"> | ||||
|                      <span id="result" class="highlightable-filter"></span> | ||||
|                  </td> | ||||
|  |  | |||
|  | @ -89,7 +89,7 @@ def test_check_basic_change_detection_functionality(client, live_server): | |||
| 
 | ||||
|     # Following the 'diff' link, it should no longer display as 'unviewed' even after we recheck it a few times | ||||
|     res = client.get(url_for("diff_history_page", uuid="first")) | ||||
|     assert b'Compare newest' in res.data | ||||
|     assert b'selected=""' in res.data, "Confirm diff history page loaded" | ||||
| 
 | ||||
|     # Check the [preview] pulls the right one | ||||
|     res = client.get( | ||||
|  |  | |||
		Ładowanie…
	
		Reference in New Issue
	
	 dgtlmoon
						dgtlmoon