Tamarin Web Tool

Tamarin-prover web interface tool.

  1. // ==UserScript==
  2. // @name Tamarin Web Tool
  3. // @namespace *
  4. // @version 2024-08-23
  5. // @description Tamarin-prover web interface tool.
  6. // @author You
  7. // @match http://127.0.0.1:*/*
  8. // @match http://localhost:*/*
  9. // @grant GM_setValue
  10. // @grant GM_getValue
  11. // @license MIT
  12. // ==/UserScript==
  13.  
  14.  
  15.  
  16.  
  17. (function () {
  18. 'use strict';
  19.  
  20. let TamarinWebTool = {
  21. running: false,
  22. breakpoints: []
  23. }
  24.  
  25. // 监听页面卸载事件
  26. window.onbeforeunload = function(e) {
  27. GM_setValue('TamarinWebTool', TamarinWebTool);
  28. };
  29.  
  30. // 在页面加载时读取数据
  31. TamarinWebTool = GM_getValue('TamarinWebTool', TamarinWebTool);
  32. console.log("Loading Tamarin Web Tool Data: ", TamarinWebTool);
  33.  
  34. function isTamarin() {
  35. let tamarin = document.querySelector('span.tamarin');
  36. return tamarin.textContent == "Tamarin"
  37. }
  38.  
  39. function addBreakPoint(bp) {
  40. TamarinWebTool.breakpoints.push(bp);
  41. }
  42.  
  43. function delBreakPoint(bp) {
  44. let index = TamarinWebTool.breakpoints.indexOf(bp);
  45. if (index !== -1) {
  46. TamarinWebTool.breakpoints.splice(index, 1);
  47. }
  48. }
  49.  
  50. function clearBreakPoints() {
  51. TamarinWebTool.breakpoints = []
  52. }
  53.  
  54. function isBreak(methods) {
  55. for (let method of methods) {
  56. let originalHTML = method.innerHTML;
  57. method.innerHTML = method.innerHTML.replaceAll('&nbsp;', '').replaceAll('<br>', '');
  58. let method_name = method.textContent.replaceAll('\n', '')
  59. method.innerHTML = originalHTML;
  60.  
  61. for (let bp of TamarinWebTool.breakpoints) {
  62. let match = method_name.match(new RegExp(bp, ''));
  63. if (match) {
  64. method.style.backgroundColor = "rgb(255, 245, 157)";
  65. return true;
  66. }
  67. }
  68. }
  69. return false;
  70. }
  71.  
  72. function run() {
  73. let xpath = '//a[@class="internal-link proof-method"]';
  74. let result = document.evaluate(xpath, document, null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null);
  75. let methods = []
  76. for (let i = 0; i < result.snapshotLength; i++) {
  77. methods.push(result.snapshotItem(i))
  78. }
  79.  
  80. if (isBreak(methods)) {
  81. TamarinWebTool.running = false;
  82. return
  83. }
  84.  
  85. if (methods.length > 0 && TamarinWebTool.running) {
  86. methods[0].click();
  87. } else {
  88. TamarinWebTool.running = false;
  89. }
  90. }
  91.  
  92. function createMenuContent() {
  93. let content = document.createElement('div');
  94. content.style.padding = '10px';
  95.  
  96. let buttons = document.createElement('div');
  97.  
  98. let runButton = document.createElement('span');
  99. runButton.textContent = '▶️';
  100. runButton.style.fontSize = '24px';
  101. runButton.style.marginLeft = '36px';
  102. runButton.style.cursor = 'pointer';
  103. runButton.onclick = function() {
  104. TamarinWebTool.running = true;
  105. run();
  106. }
  107.  
  108. let stopButton = document.createElement('span');
  109. stopButton.textContent = '⏸️';
  110. stopButton.style.fontSize = '24px';
  111. stopButton.style.marginRight = '36px';
  112. stopButton.style.float = 'right';
  113. stopButton.style.cursor = 'pointer';
  114. stopButton.onclick = function() {
  115. TamarinWebTool.running = false;
  116. }
  117.  
  118. buttons.appendChild(runButton);
  119. buttons.appendChild(stopButton);
  120. content.appendChild(buttons);
  121.  
  122. // 创建工具框容器
  123. let bpbox = document.createElement('div');
  124. bpbox.style.padding = '10px';
  125. bpbox.style.borderRadius = '5px';
  126.  
  127. // 创建输入框
  128. let bpinput = document.createElement('input');
  129. bpinput.type = 'text';
  130. bpinput.placeholder = '输入断点';
  131. bpinput.style.marginRight = '10px';
  132. bpinput.style.width = '140px';
  133.  
  134. // 创建添加按钮
  135. let addButton = document.createElement('button');
  136. addButton.textContent = '添加';
  137. addButton.style.marginRight = '10px';
  138. addButton.onclick = function() {
  139. let text = bpinput.value.trim();
  140. if (text !== '') {
  141. addBreakPoint(text);
  142.  
  143. let listItem = document.createElement('div');
  144. listItem.textContent = text;
  145. // 创建删除按钮
  146. let deleteButton = document.createElement('button');
  147. deleteButton.textContent = '删除';
  148. deleteButton.style.marginLeft = '10px';
  149. deleteButton.onclick = function() {
  150. delBreakPoint(text);
  151. bplist.removeChild(listItem);
  152. };
  153. listItem.appendChild(deleteButton);
  154. bplist.appendChild(listItem);
  155. bpinput.value = ''; // 清空输入框
  156. }
  157. };
  158.  
  159. // 创建展示框
  160. let bplist = document.createElement('div');
  161. bplist.style.marginTop = '10px';
  162.  
  163. for (let text of TamarinWebTool.breakpoints) {
  164. let listItem = document.createElement('div');
  165. listItem.textContent = text;
  166. // 创建删除按钮
  167. let deleteButton = document.createElement('button');
  168. deleteButton.textContent = '删除';
  169. deleteButton.style.marginLeft = '10px';
  170. deleteButton.onclick = function() {
  171. delBreakPoint(text);
  172. bplist.removeChild(listItem);
  173. };
  174.  
  175. listItem.appendChild(deleteButton);
  176. bplist.appendChild(listItem);
  177. }
  178.  
  179. // 创建清除按钮
  180. let clearButton = document.createElement('button');
  181. clearButton.textContent = '清除';
  182. clearButton.onclick = function() {
  183. bplist.innerHTML = ''; // 清空展示框
  184. clearBreakPoints();
  185. };
  186.  
  187. // 将元素添加到工具框
  188. bpbox.appendChild(bpinput);
  189. bpbox.appendChild(addButton);
  190. bpbox.appendChild(clearButton);
  191. bpbox.appendChild(bplist);
  192.  
  193. content.appendChild(bpbox);
  194. return content;
  195. }
  196.  
  197. function createDebugMenu() {
  198. // 创建一个新的 div 元素
  199. let floatingDiv = document.createElement('div');
  200. let header = document.createElement('div');
  201. let minimizeButton = document.createElement('button');
  202.  
  203. // 设置 header 样式
  204. header.style.backgroundColor = '#2980b9';
  205. header.style.color = 'white';
  206. header.style.padding = '10px';
  207. header.style.cursor = 'move';
  208. header.style.borderTopLeftRadius = '10px';
  209. header.style.borderTopRightRadius = '10px';
  210.  
  211. // 设置最小化按钮样式
  212. minimizeButton.textContent = '–';
  213. minimizeButton.style.float = 'right';
  214. minimizeButton.style.backgroundColor = '#2980b9';
  215. minimizeButton.style.border = 'none';
  216. minimizeButton.style.color = 'white';
  217. minimizeButton.style.cursor = 'pointer';
  218. minimizeButton.style.fontSize = '16px';
  219. minimizeButton.style.marginTop = '-10px';
  220.  
  221. // 设置浮动 div 的样式
  222. floatingDiv.style.position = 'fixed';
  223. floatingDiv.style.bottom = '20px';
  224. floatingDiv.style.right = '20px';
  225. floatingDiv.style.width = '300px';
  226. floatingDiv.style.height = '400px';
  227. floatingDiv.style.backgroundColor = '#3498db';
  228. floatingDiv.style.color = 'white';
  229. floatingDiv.style.borderRadius = '10px';
  230. floatingDiv.style.boxShadow = '0 4px 8px rgba(0, 0, 0, 0.2)';
  231. floatingDiv.style.zIndex = '9999';
  232.  
  233. // 创建content
  234. let content = createMenuContent()
  235.  
  236. // 组合元素
  237. header.appendChild(minimizeButton);
  238. floatingDiv.appendChild(header);
  239. floatingDiv.appendChild(content);
  240.  
  241. // 将 div 添加到页面 body 中
  242. document.body.appendChild(floatingDiv);
  243.  
  244. // 拖拽功能
  245. let isDragging = false;
  246. let offsetX, offsetY;
  247.  
  248. header.addEventListener('mousedown', function(event) {
  249. isDragging = true;
  250. offsetX = event.clientX - floatingDiv.getBoundingClientRect().left;
  251. offsetY = event.clientY - floatingDiv.getBoundingClientRect().top;
  252. document.addEventListener('mousemove', onMouseMove);
  253. document.addEventListener('mouseup', onMouseUp);
  254. });
  255.  
  256. function onMouseMove(event) {
  257. if (isDragging) {
  258. floatingDiv.style.left = (event.clientX - offsetX) + 'px';
  259. floatingDiv.style.top = (event.clientY - offsetY) + 'px';
  260. }
  261. }
  262.  
  263. function onMouseUp() {
  264. isDragging = false;
  265. document.removeEventListener('mousemove', onMouseMove);
  266. document.removeEventListener('mouseup', onMouseUp);
  267. }
  268.  
  269. // 最小化功能
  270. minimizeButton.addEventListener('click', function() {
  271. if (content.style.display === 'none') {
  272. content.style.display = 'block';
  273. minimizeButton.textContent = '–';
  274. floatingDiv.style.width = '300px';
  275. floatingDiv.style.height = '400px';
  276. } else {
  277. content.style.display = 'none';
  278. minimizeButton.textContent = '+';
  279. floatingDiv.style.width = '300px';
  280. floatingDiv.style.height = '30px';
  281. }
  282. });
  283. }
  284.  
  285.  
  286. if (isTamarin()) {
  287. createDebugMenu()
  288. if (TamarinWebTool.running) {
  289. run()
  290. }
  291. }
  292. })();

QingJ © 2025

镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址