umap-project 3.2.0__py3-none-any.whl → 3.3.1__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of umap-project might be problematic. Click here for more details.

Files changed (179) hide show
  1. umap/__init__.py +1 -1
  2. umap/locale/el/LC_MESSAGES/django.mo +0 -0
  3. umap/locale/el/LC_MESSAGES/django.po +42 -38
  4. umap/locale/en/LC_MESSAGES/django.mo +0 -0
  5. umap/locale/en/LC_MESSAGES/django.po +15 -15
  6. umap/locale/hu/LC_MESSAGES/django.mo +0 -0
  7. umap/locale/hu/LC_MESSAGES/django.po +39 -35
  8. umap/locale/nl/LC_MESSAGES/django.mo +0 -0
  9. umap/locale/nl/LC_MESSAGES/django.po +31 -27
  10. umap/settings/base.py +2 -0
  11. umap/static/umap/css/contextmenu.css +58 -2
  12. umap/static/umap/css/form.css +175 -45
  13. umap/static/umap/css/icon.css +20 -0
  14. umap/static/umap/img/16-white.svg +21 -40
  15. umap/static/umap/img/16.svg +1 -1
  16. umap/static/umap/img/24-white.svg +9 -9
  17. umap/static/umap/img/24.svg +23 -10
  18. umap/static/umap/img/source/16-white.svg +23 -41
  19. umap/static/umap/img/source/16.svg +1 -1
  20. umap/static/umap/img/source/24-white.svg +11 -11
  21. umap/static/umap/img/source/24.svg +25 -12
  22. umap/static/umap/js/modules/caption.js +8 -0
  23. umap/static/umap/js/modules/data/features.js +318 -174
  24. umap/static/umap/js/modules/data/layer.js +27 -20
  25. umap/static/umap/js/modules/form/builder.js +11 -7
  26. umap/static/umap/js/modules/form/fields.js +10 -7
  27. umap/static/umap/js/modules/formatter.js +42 -20
  28. umap/static/umap/js/modules/importer.js +6 -1
  29. umap/static/umap/js/modules/importers/opendata.js +125 -37
  30. umap/static/umap/js/modules/importers/openrouteservice.js +140 -0
  31. umap/static/umap/js/modules/managers.js +12 -4
  32. umap/static/umap/js/modules/printer.js +107 -0
  33. umap/static/umap/js/modules/rendering/controls.js +78 -2
  34. umap/static/umap/js/modules/rendering/icon.js +113 -82
  35. umap/static/umap/js/modules/rendering/layers/cluster.js +220 -64
  36. umap/static/umap/js/modules/rendering/map.js +5 -1
  37. umap/static/umap/js/modules/rendering/template.js +71 -1
  38. umap/static/umap/js/modules/rendering/ui.js +101 -34
  39. umap/static/umap/js/modules/schema.js +24 -0
  40. umap/static/umap/js/modules/share.js +19 -12
  41. umap/static/umap/js/modules/ui/bar.js +6 -1
  42. umap/static/umap/js/modules/ui/base.js +24 -9
  43. umap/static/umap/js/modules/ui/contextmenu.js +17 -7
  44. umap/static/umap/js/modules/ui/dialog.js +7 -4
  45. umap/static/umap/js/modules/umap.js +68 -62
  46. umap/static/umap/js/umap.controls.js +22 -57
  47. umap/static/umap/locale/am_ET.js +39 -4
  48. umap/static/umap/locale/am_ET.json +39 -4
  49. umap/static/umap/locale/ar.js +39 -4
  50. umap/static/umap/locale/ar.json +39 -4
  51. umap/static/umap/locale/ast.js +39 -4
  52. umap/static/umap/locale/ast.json +39 -4
  53. umap/static/umap/locale/bg.js +39 -4
  54. umap/static/umap/locale/bg.json +39 -4
  55. umap/static/umap/locale/br.js +39 -4
  56. umap/static/umap/locale/br.json +39 -4
  57. umap/static/umap/locale/ca.js +39 -4
  58. umap/static/umap/locale/ca.json +39 -4
  59. umap/static/umap/locale/cs_CZ.js +39 -4
  60. umap/static/umap/locale/cs_CZ.json +39 -4
  61. umap/static/umap/locale/da.js +47 -12
  62. umap/static/umap/locale/da.json +47 -12
  63. umap/static/umap/locale/de.js +39 -4
  64. umap/static/umap/locale/de.json +39 -4
  65. umap/static/umap/locale/el.js +81 -46
  66. umap/static/umap/locale/el.json +81 -46
  67. umap/static/umap/locale/en.js +38 -4
  68. umap/static/umap/locale/en.json +38 -4
  69. umap/static/umap/locale/en_US.json +39 -4
  70. umap/static/umap/locale/es.js +47 -12
  71. umap/static/umap/locale/es.json +47 -12
  72. umap/static/umap/locale/et.js +39 -4
  73. umap/static/umap/locale/et.json +39 -4
  74. umap/static/umap/locale/eu.js +80 -45
  75. umap/static/umap/locale/eu.json +80 -45
  76. umap/static/umap/locale/fa_IR.js +39 -4
  77. umap/static/umap/locale/fa_IR.json +39 -4
  78. umap/static/umap/locale/fi.js +39 -4
  79. umap/static/umap/locale/fi.json +39 -4
  80. umap/static/umap/locale/fr.js +39 -4
  81. umap/static/umap/locale/fr.json +39 -4
  82. umap/static/umap/locale/gl.js +39 -4
  83. umap/static/umap/locale/gl.json +39 -4
  84. umap/static/umap/locale/he.js +39 -4
  85. umap/static/umap/locale/he.json +39 -4
  86. umap/static/umap/locale/hr.js +39 -4
  87. umap/static/umap/locale/hr.json +39 -4
  88. umap/static/umap/locale/hu.js +55 -20
  89. umap/static/umap/locale/hu.json +55 -20
  90. umap/static/umap/locale/id.js +39 -4
  91. umap/static/umap/locale/id.json +39 -4
  92. umap/static/umap/locale/is.js +39 -4
  93. umap/static/umap/locale/is.json +39 -4
  94. umap/static/umap/locale/it.js +39 -4
  95. umap/static/umap/locale/it.json +39 -4
  96. umap/static/umap/locale/ja.js +39 -4
  97. umap/static/umap/locale/ja.json +39 -4
  98. umap/static/umap/locale/ko.js +39 -4
  99. umap/static/umap/locale/ko.json +39 -4
  100. umap/static/umap/locale/lt.js +39 -4
  101. umap/static/umap/locale/lt.json +39 -4
  102. umap/static/umap/locale/ms.js +52 -17
  103. umap/static/umap/locale/ms.json +52 -17
  104. umap/static/umap/locale/nl.js +58 -23
  105. umap/static/umap/locale/nl.json +58 -23
  106. umap/static/umap/locale/no.js +39 -4
  107. umap/static/umap/locale/no.json +39 -4
  108. umap/static/umap/locale/pl.js +39 -4
  109. umap/static/umap/locale/pl.json +39 -4
  110. umap/static/umap/locale/pl_PL.json +39 -4
  111. umap/static/umap/locale/pt.js +39 -4
  112. umap/static/umap/locale/pt.json +39 -4
  113. umap/static/umap/locale/pt_BR.js +39 -4
  114. umap/static/umap/locale/pt_BR.json +39 -4
  115. umap/static/umap/locale/pt_PT.js +39 -4
  116. umap/static/umap/locale/pt_PT.json +39 -4
  117. umap/static/umap/locale/ro.js +39 -4
  118. umap/static/umap/locale/ro.json +39 -4
  119. umap/static/umap/locale/ru.js +39 -4
  120. umap/static/umap/locale/ru.json +39 -4
  121. umap/static/umap/locale/sk_SK.js +39 -4
  122. umap/static/umap/locale/sk_SK.json +39 -4
  123. umap/static/umap/locale/sl.js +39 -4
  124. umap/static/umap/locale/sl.json +39 -4
  125. umap/static/umap/locale/sr.js +39 -4
  126. umap/static/umap/locale/sr.json +39 -4
  127. umap/static/umap/locale/sv.js +39 -4
  128. umap/static/umap/locale/sv.json +39 -4
  129. umap/static/umap/locale/th_TH.js +39 -4
  130. umap/static/umap/locale/th_TH.json +39 -4
  131. umap/static/umap/locale/tr.js +39 -4
  132. umap/static/umap/locale/tr.json +39 -4
  133. umap/static/umap/locale/uk_UA.js +39 -4
  134. umap/static/umap/locale/uk_UA.json +39 -4
  135. umap/static/umap/locale/vi.js +39 -4
  136. umap/static/umap/locale/vi.json +39 -4
  137. umap/static/umap/locale/vi_VN.json +39 -4
  138. umap/static/umap/locale/zh.js +39 -4
  139. umap/static/umap/locale/zh.json +39 -4
  140. umap/static/umap/locale/zh_CN.json +39 -4
  141. umap/static/umap/locale/zh_TW.Big5.json +39 -4
  142. umap/static/umap/locale/zh_TW.js +98 -63
  143. umap/static/umap/locale/zh_TW.json +98 -63
  144. umap/static/umap/map.css +90 -41
  145. umap/static/umap/vars.css +1 -0
  146. umap/static/umap/vendors/editable/Leaflet.Editable.js +3 -1
  147. umap/static/umap/vendors/openrouteservice/ors-js-client.js +521 -0
  148. umap/static/umap/vendors/openrouteservice/ors-js-client.js.map +1 -0
  149. umap/static/umap/vendors/simple-elevation-chart/elevation.js +63 -0
  150. umap/static/umap/vendors/simple-elevation-chart/elevation.svg +8 -0
  151. umap/static/umap/vendors/snapdom/snapdom.min.mjs +3 -0
  152. umap/storage/staticfiles.py +12 -0
  153. umap/templates/umap/css.html +0 -4
  154. umap/templates/umap/js.html +1 -3
  155. umap/tests/integration/test_basics.py +2 -0
  156. umap/tests/integration/test_conditional_rules.py +17 -17
  157. umap/tests/integration/test_datalayer.py +1 -1
  158. umap/tests/integration/test_draw_polygon.py +3 -5
  159. umap/tests/integration/test_draw_polyline.py +4 -6
  160. umap/tests/integration/test_draw_route.py +178 -0
  161. umap/tests/integration/test_edit_map.py +1 -1
  162. umap/tests/integration/test_edit_marker.py +7 -7
  163. umap/tests/integration/test_edit_polygon.py +2 -2
  164. umap/tests/integration/test_export_map.py +74 -10
  165. umap/tests/integration/test_map_preview.py +1 -1
  166. umap/tests/integration/test_share.py +1 -1
  167. umap/tests/integration/test_tableeditor.py +4 -4
  168. umap/tests/integration/test_websocket_sync.py +4 -4
  169. umap/utils.py +5 -1
  170. umap/views.py +2 -0
  171. {umap_project-3.2.0.dist-info → umap_project-3.3.1.dist-info}/METADATA +9 -9
  172. {umap_project-3.2.0.dist-info → umap_project-3.3.1.dist-info}/RECORD +175 -171
  173. umap/static/umap/vendors/markercluster/MarkerCluster.Default.css +0 -60
  174. umap/static/umap/vendors/markercluster/MarkerCluster.css +0 -14
  175. umap/static/umap/vendors/markercluster/leaflet.markercluster.js +0 -2
  176. umap/static/umap/vendors/markercluster/leaflet.markercluster.js.map +0 -1
  177. {umap_project-3.2.0.dist-info → umap_project-3.3.1.dist-info}/WHEEL +0 -0
  178. {umap_project-3.2.0.dist-info → umap_project-3.3.1.dist-info}/entry_points.txt +0 -0
  179. {umap_project-3.2.0.dist-info → umap_project-3.3.1.dist-info}/licenses/LICENSE +0 -0
@@ -0,0 +1,3 @@
1
+ var l={image:new Map,background:new Map,resource:new Map,defaultStyle:new Map,baseStyle:new Map,computedStyle:new WeakMap,font:new Set,snapshot:new WeakMap,snapshotKey:new Map,preStyleMap:new Map,preStyle:new WeakMap,preNodeMap:new Map,reset:Re};function Re(){l.computedStyle=new WeakMap,l.snapshot=new WeakMap,l.snapshotKey.clear(),l.preStyleMap.clear(),l.preStyle=new WeakMap,l.preNodeMap.clear()}var Ne=["div","span","p","a","img","ul","li","button","input","select","textarea","label","section","article","header","footer","nav","main","aside","h1","h2","h3","h4","h5","h6","svg","path","circle","rect","line","g","table","thead","tbody","tr","td","th"];function ie(){for(let e of Ne)ce(e)}function ce(e){if(l.defaultStyle.has(e))return l.defaultStyle.get(e);if(new Set(["script","style","meta","link","noscript","template","defs","symbol","title","metadata","desc"]).has(e)){let n={};return l.defaultStyle.set(e,n),n}let r=document.getElementById("snapdom-sandbox");r||(r=document.createElement("div"),r.id="snapdom-sandbox",r.style.position="absolute",r.style.left="-9999px",r.style.top="-9999px",r.style.width="0",r.style.height="0",r.style.overflow="hidden",document.body.appendChild(r));let c=document.createElement(e);c.style.all="initial",r.appendChild(c);let s=getComputedStyle(c),o={};for(let n of s)o[n]=s.getPropertyValue(n);return r.removeChild(c),l.defaultStyle.set(e,o),o}var Ae=new Set(["-webkit-locale"]);function D(e,t,r=!1){let c=[],s=ce(t);for(let[o,n]of Object.entries(e))if(!Ae.has(o))if(!r)n&&c.push(`${o}:${n}`);else{let a=s[o];n&&n!==a&&c.push(`${o}:${n}`)}return c.sort().join(";")}function le(e){let t=new Set;return e.nodeType!==Node.ELEMENT_NODE&&e.nodeType!==Node.DOCUMENT_FRAGMENT_NODE?[]:(e.tagName&&t.add(e.tagName.toLowerCase()),typeof e.querySelectorAll=="function"&&e.querySelectorAll("*").forEach(r=>t.add(r.tagName.toLowerCase())),Array.from(t))}function de(e){let t=new Map;for(let c of e){let s=l.defaultStyle.get(c);if(!s)continue;let o=Object.entries(s).map(([n,a])=>`${n}:${a};`).sort().join("");t.has(o)||t.set(o,[]),t.get(o).push(c)}let r="";for(let[c,s]of t.entries())r+=`${s.join(",")} { ${c} }
2
+ `;return r}function fe(){let e=new Set(l.preStyleMap.values()),t=new Map,r=1;for(let c of e)c.trim()&&t.set(c,`c${r++}`);return t}async function P(e,t={}){let r=O(e),c=/^((repeating-)?(linear|radial|conic)-gradient)\(/i.test(e);if(r){let s=H(r);if(l.background.has(s))return t.skipInline?void 0:`url(${l.background.get(s)})`;{let o=await M(s,{useProxy:t.useProxy});return l.background.set(s,o),t.skipInline?void 0:`url("${o}")`}}return e}function F(e,{fast:t=!1}={}){if(t)return e();"requestIdleCallback"in window?requestIdleCallback(e,{timeout:50}):setTimeout(e,1)}function I(e,t=null){if(!(e instanceof Element))return window.getComputedStyle(e,t);let r=l.computedStyle.get(e);if(r||(r=new Map,l.computedStyle.set(e,r)),!r.has(t)){let c=window.getComputedStyle(e,t);r.set(t,c)}return r.get(t)}function ue(e){let t=e.replace(/^['"]|['"]$/g,"");if(t.startsWith("\\"))try{return String.fromCharCode(parseInt(t.replace("\\",""),16))}catch{return t}return t}function O(e){let t=e.match(/url\((['"]?)(.*?)(\1)\)/);if(!t)return null;let r=t[2].trim();return r.startsWith("#")?null:r}function M(e,{timeout:t=3e3,useProxy:r=""}={}){function c(i){try{return new URL(i,window.location.href).origin===window.location.origin?"use-credentials":"anonymous"}catch{return"anonymous"}}async function s(i){let d=u=>fetch(u,{mode:"cors",credentials:c(u)==="use-credentials"?"include":"omit"}).then(f=>f.blob()).then(f=>new Promise((m,p)=>{let h=new FileReader;h.onloadend=()=>{let y=h.result;if(typeof y!="string"||!y.startsWith("data:image/")){p(new Error("Invalid image data URL"));return}m(y)},h.onerror=()=>p(new Error("FileReader error")),h.readAsDataURL(f)}));try{return await d(i)}catch{if(r&&typeof r=="string"){let f=r.replace(/\/$/,"")+H(i);try{return await d(f)}catch{throw new Error("[SnapDOM - fetchImage] CORS restrictions prevented image capture (even via proxy)")}}else throw new Error("[SnapDOM - fetchImage] Fetch fallback failed and no proxy provided")}}let o=c(e);return l.image.has(e)?Promise.resolve(l.image.get(e)):e.startsWith("data:image/")?(l.image.set(e,e),Promise.resolve(e)):/\.svg(\?.*)?$/i.test(e)?(async()=>{try{let d=await(await fetch(e,{mode:"cors",credentials:o==="use-credentials"?"include":"omit"})).text(),u=`data:image/svg+xml;charset=utf-8,${encodeURIComponent(d)}`;return l.image.set(e,u),u}catch{return s(e)}})():new Promise((i,d)=>{let u=setTimeout(()=>{d(new Error("[SnapDOM - fetchImage] Image load timed out"))},t),f=new Image;f.crossOrigin=o,f.onload=async()=>{clearTimeout(u);try{await f.decode();let m=document.createElement("canvas");m.width=f.width,m.height=f.height,m.getContext("2d").drawImage(f,0,0,m.width,m.height);let h=m.toDataURL("image/png");l.image.set(e,h),i(h)}catch{try{let m=await s(e);l.image.set(e,m),i(m)}catch(m){d(m)}}},f.onerror=async()=>{clearTimeout(u),console.error(`[SnapDOM - fetchImage] Image failed to load: ${e}`);try{let m=await s(e);l.image.set(e,m),i(m)}catch(m){d(m)}},f.src=e})}function Q(e){let t={};for(let r of e)t[r]=e.getPropertyValue(r);return t}function me(){return/^((?!chrome|android).)*safari/i.test(navigator.userAgent)}function pe(e){if(!e||e==="none")return"";let t=e.replace(/translate[XY]?\([^)]*\)/g,"");return t=t.replace(/matrix\(([^)]+)\)/g,(r,c)=>{let s=c.split(",").map(o=>o.trim());return s.length!==6?`matrix(${c})`:(s[4]="0",s[5]="0",`matrix(${s.join(", ")})`)}),t=t.replace(/matrix3d\(([^)]+)\)/g,(r,c)=>{let s=c.split(",").map(o=>o.trim());return s.length!==16?`matrix3d(${c})`:(s[12]="0",s[13]="0",`matrix3d(${s.join(", ")})`)}),t.trim().replace(/\s{2,}/g," ")}function H(e){if(/%[0-9A-Fa-f]{2}/.test(e))return e;try{return encodeURI(e)}catch{return e}}function U(e){let t=[],r=0,c=0;for(let s=0;s<e.length;s++){let o=e[s];o==="("&&r++,o===")"&&r--,o===","&&r===0&&(t.push(e.slice(c,s).trim()),c=s+1)}return t.push(e.slice(c).trim()),t}function Te(e){let t={},r=e.getPropertyValue("visibility");for(let c=0;c<e.length;c++){let s=e[c],o=e.getPropertyValue(s);(s==="background-image"||s==="content")&&o.includes("url(")&&!o.includes("data:")&&(o="none"),t[s]=o}return r==="hidden"&&(t.opacity="0"),t}function z(e,t,r){if(e.tagName==="STYLE")return;l.preStyle.has(e)||l.preStyle.set(e,I(e));let c=l.preStyle.get(e);if(!l.snapshot.has(e)){let i=Te(c);l.snapshot.set(e,i)}let s=l.snapshot.get(e),o=Object.entries(s).sort(([i],[d])=>i.localeCompare(d)).map(([i,d])=>`${i}:${d}`).join(";");if(l.snapshotKey.has(o)){l.preStyleMap.set(t,l.snapshotKey.get(o));return}let n=e.tagName?.toLowerCase()||"div",a=D(s,n,r);l.snapshotKey.set(o,a),l.preStyleMap.set(t,a)}function j(e,t,r={},c){if(!e)throw new Error("Invalid node");let s=new Set,o=null;if(e.nodeType===Node.TEXT_NODE||e.nodeType!==Node.ELEMENT_NODE)return e.cloneNode(!0);if(e.getAttribute("data-capture")==="exclude"){let a=document.createElement("div"),i=e.getBoundingClientRect();return a.style.cssText=`display:inline-block;width:${i.width}px;height:${i.height}px;visibility:hidden;`,a}if(r.exclude&&Array.isArray(r.exclude))for(let a of r.exclude)try{if(e.matches?.(a)){let i=document.createElement("div"),d=e.getBoundingClientRect();return i.style.cssText=`display:inline-block;width:${d.width}px;height:${d.height}px;visibility:hidden;`,i}}catch(i){console.warn(`Invalid selector in exclude option: ${a}`,i)}if(typeof r.filter=="function")try{if(!r.filter(e,c||e)){let a=document.createElement("div"),i=e.getBoundingClientRect();return a.style.cssText=`display:inline-block;width:${i.width}px;height:${i.height}px;visibility:hidden;`,a}}catch(a){console.warn("Error in filter function:",a)}if(e.tagName==="IFRAME"){let a=document.createElement("div");return a.style.cssText=`width:${e.offsetWidth}px;height:${e.offsetHeight}px;background-image:repeating-linear-gradient(45deg,#ddd,#ddd 5px,#f9f9f9 5px,#f9f9f9 10px);display:flex;align-items:center;justify-content:center;font-size:12px;color:#555;border:1px solid #aaa;`,a}if(e.getAttribute("data-capture")==="placeholder"){let a=e.cloneNode(!1);l.preNodeMap.set(a,e),z(e,a,t);let i=document.createElement("div");return i.textContent=e.getAttribute("data-placeholder-text")||"",i.style.cssText="color:#666;font-size:12px;text-align:center;line-height:1.4;padding:0.5em;box-sizing:border-box;",a.appendChild(i),a}if(e.tagName==="CANVAS"){let a=e.toDataURL(),i=document.createElement("img");return i.src=a,i.width=e.width,i.height=e.height,l.preNodeMap.set(i,e),z(e,i,t),i}let n;try{n=e.cloneNode(!1),l.preNodeMap.set(n,e)}catch(a){throw console.error("[Snapdom] Failed to clone node:",e,a),a}if(e instanceof HTMLTextAreaElement){n.textContent=e.value,n.value=e.value;let a=e.getBoundingClientRect();return n.style.width=`${a.width}px`,n.style.height=`${a.height}px`,n}if(e instanceof HTMLInputElement&&(n.value=e.value,n.setAttribute("value",e.value),e.checked!==void 0&&(n.checked=e.checked,e.checked&&n.setAttribute("checked",""),e.indeterminate&&(n.indeterminate=e.indeterminate))),e instanceof HTMLSelectElement&&(o=e.value),z(e,n,t),e.shadowRoot)if(Array.from(e.shadowRoot.querySelectorAll("slot")).length>0){for(let i of e.shadowRoot.childNodes)if(i.nodeType===Node.ELEMENT_NODE&&i.tagName==="STYLE"){let d=i.textContent||"";d.trim()&&t&&(l.preStyle||(l.preStyle=new WeakMap),l.preStyle.set(i,d))}}else{let i=document.createDocumentFragment();for(let d of e.shadowRoot.childNodes){if(d.nodeType===Node.ELEMENT_NODE&&d.tagName==="STYLE"){let f=d.textContent||"";f.trim()&&t&&(l.preStyle||(l.preStyle=new WeakMap),l.preStyle.set(d,f));continue}let u=j(d,t,r,c||e);u&&i.appendChild(u)}n.appendChild(i)}if(e.tagName==="SLOT"){let a=e.assignedNodes?.({flatten:!0})||[],i=a.length>0?a:Array.from(e.childNodes),d=document.createDocumentFragment();for(let u of i){let f=j(u,t,r,c||e);f&&d.appendChild(f)}return d}for(let a of e.childNodes){if(s.has(a))continue;let i=j(a,t,r,c||e);i&&n.appendChild(i)}if(o!==null&&n instanceof HTMLSelectElement){n.value=o;for(let a of n.options)a.value===o?a.setAttribute("selected",""):a.removeAttribute("selected")}return n}var Me=[/font\s*awesome/i,/material\s*icons/i,/ionicons/i,/glyphicons/i,/feather/i,/bootstrap\s*icons/i,/remix\s*icons/i,/heroicons/i,/layui/i,/lucide/i],Z=[];function he(e){let t=Array.isArray(e)?e:[e];for(let r of t)r instanceof RegExp?Z.push(r):typeof r=="string"?Z.push(new RegExp(r,"i")):console.warn("[snapdom] Ignored invalid iconFont value:",r)}function k(e){let t=typeof e=="string"?e:"",r=[...Me,...Z];for(let c of r)if(c instanceof RegExp&&c.test(t))return!0;return!!(/icon/i.test(t)||/glyph/i.test(t)||/symbols/i.test(t)||/feather/i.test(t)||/fontawesome/i.test(t))}async function ge(e,t,r,c=32,s="#000"){t=t.replace(/^['"]+|['"]+$/g,"");let o=window.devicePixelRatio||1;await document.fonts.ready;let n=document.createElement("span");n.textContent=e,n.style.position="absolute",n.style.visibility="hidden",n.style.fontFamily=`"${t}"`,n.style.fontWeight=r||"normal",n.style.fontSize=`${c}px`,n.style.lineHeight="1",n.style.whiteSpace="nowrap",n.style.padding="0",n.style.margin="0",document.body.appendChild(n);let a=n.getBoundingClientRect(),i=Math.ceil(a.width),d=Math.ceil(a.height);document.body.removeChild(n);let u=document.createElement("canvas");u.width=i*o,u.height=d*o;let f=u.getContext("2d");return f.scale(o,o),f.font=r?`${r} ${c}px "${t}"`:`${c}px "${t}"`,f.textAlign="left",f.textBaseline="top",f.fillStyle=s,f.fillText(e,0,0),{dataUrl:u.toDataURL(),width:i,height:d}}function ye(e){return Array.from(document.styleSheets).some(t=>t.href===e)}function Le(e){return new Promise(t=>{if(ye(e))return t(null);let r=document.createElement("link");r.rel="stylesheet",r.href=e,r.setAttribute("data-snapdom","injected-import"),r.onload=()=>t(r),r.onerror=()=>t(null),document.head.appendChild(r)})}async function K({preCached:e=!1}={}){if(l.resource.has("fonts-embed-css")){if(e){let o=document.createElement("style");o.setAttribute("data-snapdom","embedFonts"),o.textContent=l.resource.get("fonts-embed-css"),document.head.appendChild(o)}return l.resource.get("fonts-embed-css")}let t=/@import\s+url\(["']?([^"')]+)["']?\)/g,r=[];for(let o of document.querySelectorAll("style")){let n=o.textContent||"",a=Array.from(n.matchAll(t));for(let i of a){let d=i[1];k(d)||ye(d)||r.push(d)}}await Promise.all(r.map(Le));let c=Array.from(document.querySelectorAll('link[rel="stylesheet"]')).filter(o=>o.href),s="";for(let o of c)try{let a=await(await fetch(o.href)).text();if(k(o.href)||k(a))continue;let i=/url\((["']?)([^"')]+)\1\)/g,d=await Promise.all(Array.from(a.matchAll(i)).map(async f=>{let m=O(f[0]);if(!m)return null;let p=m;if(!p.startsWith("http")&&!p.startsWith("data:")&&(p=new URL(p,o.href).href),k(p))return null;if(l.resource.has(p))return l.font.add(p),{original:f[0],inlined:`url(${l.resource.get(p)})`};if(l.font.has(p))return null;try{let y=await(await fetch(p)).blob(),w=await new Promise(g=>{let E=new FileReader;E.onload=()=>g(E.result),E.readAsDataURL(y)});return l.resource.set(p,w),l.font.add(p),{original:f[0],inlined:`url(${w})`}}catch{return console.warn("[snapdom] Failed to fetch font resource:",p),null}})),u=a;for(let f of d)f&&(u=u.replace(f.original,f.inlined));s+=u+`
3
+ `}catch{console.warn("[snapdom] Failed to fetch CSS:",o.href)}for(let o of document.styleSheets)try{if(!o.href||c.every(n=>n.href!==o.href)){for(let n of o.cssRules)if(n.type===CSSRule.FONT_FACE_RULE){let a=n.style.getPropertyValue("src"),i=n.style.getPropertyValue("font-family");if(!a||k(i))continue;let d=/url\((["']?)([^"')]+)\1\)/g,u=/local\((["']?)[^)]+?\1\)/g,f=!!a.match(d),m=!!a.match(u);if(!f&&m){s+=`@font-face{font-family:${i};src:${a};font-style:${n.style.getPropertyValue("font-style")||"normal"};font-weight:${n.style.getPropertyValue("font-weight")||"normal"};}`;continue}let p=a,h=Array.from(a.matchAll(d));for(let y of h){let w=y[2].trim();if(!w)continue;let g=w;if(!g.startsWith("http")&&!g.startsWith("data:")&&(g=new URL(g,o.href||location.href).href),!k(g)){if(l.resource.has(g)){l.font.add(g),p=p.replace(y[0],`url(${l.resource.get(g)})`);continue}if(!l.font.has(g))try{let $=await(await fetch(g)).blob(),R=await new Promise(N=>{let x=new FileReader;x.onload=()=>N(x.result),x.readAsDataURL($)});l.resource.set(g,R),l.font.add(g),p=p.replace(y[0],`url(${R})`)}catch{console.warn("[snapdom] Failed to fetch font URL:",g)}}}s+=`@font-face{font-family:${i};src:${p};font-style:${n.style.getPropertyValue("font-style")||"normal"};font-weight:${n.style.getPropertyValue("font-weight")||"normal"};}`}}}catch(n){console.warn("[snapdom] Cannot access stylesheet",o.href,n)}for(let o of document.fonts)if(o.family&&o.status==="loaded"&&o._snapdomSrc){if(k(o.family))continue;let n=o._snapdomSrc;if(!n.startsWith("data:")){if(l.resource.has(o._snapdomSrc))n=l.resource.get(o._snapdomSrc),l.font.add(o._snapdomSrc);else if(!l.font.has(o._snapdomSrc))try{let i=await(await fetch(o._snapdomSrc)).blob();n=await new Promise(d=>{let u=new FileReader;u.onload=()=>d(u.result),u.readAsDataURL(i)}),l.resource.set(o._snapdomSrc,n),l.font.add(o._snapdomSrc)}catch{console.warn("[snapdom] Failed to fetch dynamic font src:",o._snapdomSrc);continue}}s+=`@font-face{font-family:'${o.family}';src:url(${n});font-style:${o.style||"normal"};font-weight:${o.weight||"normal"};}`}if(s&&(l.resource.set("fonts-embed-css",s),e)){let o=document.createElement("style");o.setAttribute("data-snapdom","embedFonts"),o.textContent=s,document.head.appendChild(o)}return s}async function ee(e,t,r){if(!(e instanceof Element)||!(t instanceof Element))return;for(let o of["::before","::after","::first-letter"])try{let n=I(e,o);if(!n||typeof n[Symbol.iterator]!="function"||n.content==="none"&&n.backgroundImage==="none"&&n.backgroundColor==="transparent"&&(n.borderStyle==="none"||parseFloat(n.borderWidth)===0)&&(!n.transform||n.transform==="none")&&n.display==="inline")continue;if(o==="::first-letter"){let C=getComputedStyle(e);if(!(n.color!==C.color||n.fontSize!==C.fontSize||n.fontWeight!==C.fontWeight))continue;let T=Array.from(t.childNodes).find(se=>se.nodeType===Node.TEXT_NODE&&se.textContent?.trim().length>0);if(!T)continue;let L=T.textContent,_=L.match(/^([^\p{L}\p{N}\s]*[\p{L}\p{N}](?:['’])?)/u)?.[0],ke=L.slice(_?.length||0);if(!_||/[\uD800-\uDFFF]/.test(_))continue;let q=document.createElement("span");q.textContent=_,q.dataset.snapdomPseudo="::first-letter";let $e=Q(n),Ie=D($e,"span",r);l.preStyleMap.set(q,Ie);let ae=document.createTextNode(ke);t.replaceChild(ae,T),t.insertBefore(q,ae);continue}let i=n.content,d=/counter\s*\(|counters\s*\(/.test(i)?"- ":ue(i),u=n.backgroundImage,f=n.backgroundColor,m=n.fontFamily,p=parseInt(n.fontSize)||32,h=parseInt(n.fontWeight)||!1,y=n.color||"#000",w=n.display,g=parseFloat(n.width),E=parseFloat(n.height),$=n.borderStyle,R=parseFloat(n.borderWidth),N=n.transform,x=k(m),B=i!=="none"&&d!=="",V=u&&u!=="none",W=f&&f!=="transparent"&&f!=="rgba(0, 0, 0, 0)",Y=w!=="inline"&&(g>0||E>0),G=$&&$!=="none"&&R>0,A=N&&N!=="none";if(!(B||V||W||Y||G||A))continue;let S=document.createElement("span");S.dataset.snapdomPseudo=o,S.style.verticalAlign="middle";let X=Q(n),J=D(X,"span",r);if(l.preStyleMap.set(S,J),x&&d.length===1){let{dataUrl:C,width:v,height:T}=await ge(d,m,h,p,y),L=document.createElement("img");L.src=C,L.style=`height:${p}px;width:${v/T*p}px;object-fit:contain;`,S.appendChild(L),t.dataset.snapdomHasIcon="true"}else if(d.startsWith("url(")){let C=O(d);if(C?.trim())try{let v=document.createElement("img"),T=await M(H(C),r);v.src=T,v.style=`width:${p}px;height:auto;object-fit:contain;`,S.appendChild(v)}catch(v){console.error(`[snapdom] Error in pseudo ${o} for`,e,v)}}else!x&&B&&(S.textContent=d);if(V)try{let C=U(u),v=await Promise.all(C.map(P));S.style.backgroundImage=v.join(", ")}catch(C){console.warn(`[snapdom] Failed to inline background-image for ${o}`,C)}if(W&&(S.style.backgroundColor=f),!(S.childNodes.length>0||S.textContent?.trim()!==""||V||W||Y||G||A))continue;o==="::before"?t.insertBefore(S,t.firstChild):t.appendChild(S)}catch(n){console.warn(`[snapdom] Failed to capture ${o} for`,e,n)}let c=Array.from(e.children),s=Array.from(t.children).filter(o=>!o.dataset.snapdomPseudo);for(let o=0;o<Math.min(c.length,s.length);o++)await ee(c[o],s[o],r)}function we(e){if(!e)return;let t=new Set;if(e.querySelectorAll("use").forEach(a=>{let i=a.getAttribute("xlink:href")||a.getAttribute("href");i&&i.startsWith("#")&&t.add(i.slice(1))}),!t.size)return;let r=Array.from(document.querySelectorAll("svg > symbol, svg > defs")),c=r.filter(a=>a.tagName.toLowerCase()==="symbol"),s=r.filter(a=>a.tagName.toLowerCase()==="defs"),o=e.querySelector("svg.inline-defs-container");o||(o=document.createElementNS("http://www.w3.org/2000/svg","svg"),o.setAttribute("aria-hidden","true"),o.setAttribute("style","position: absolute; width: 0; height: 0; overflow: hidden;"),o.classList.add("inline-defs-container"),e.insertBefore(o,e.firstChild));let n=new Set;e.querySelectorAll("symbol[id], defs > *[id]").forEach(a=>{n.add(a.id)}),t.forEach(a=>{if(n.has(a))return;let i=c.find(d=>d.id===a);if(i){o.appendChild(i.cloneNode(!0)),n.add(a);return}for(let d of s){let u=d.querySelector(`#${CSS.escape(a)}`);if(u){let f=o.querySelector("defs");f||(f=document.createElementNS("http://www.w3.org/2000/svg","defs"),o.appendChild(f)),f.appendChild(u.cloneNode(!0)),n.add(a);break}}})}async function be(e,t=!1,r=!1,c={}){let s,o="";Pe(e);try{we(e)}catch(n){console.warn("inlineExternal defs or symbol failed:",n)}try{s=j(e,t,c,e)}catch(n){throw console.warn("deepClone failed:",n),n}try{await ee(e,s,t,r,c.useProxy)}catch(n){console.warn("inlinePseudoElements failed:",n)}if(t){let n=fe();o=Array.from(n.entries()).map(([a,i])=>`.${i}{${a}}`).join("");for(let[a,i]of l.preStyleMap.entries()){if(a.tagName==="STYLE")continue;if(a.getRootNode&&a.getRootNode()instanceof ShadowRoot){a.setAttribute("style",i.replace(/;/g,"; "));continue}let d=n.get(i);d&&a.classList.add(d);let u=a.style?.backgroundImage,f=a.dataset?.snapdomHasIcon;u&&u!=="none"&&(a.style.backgroundImage=u),f&&(a.style.verticalAlign="middle",a.style.display="inline")}}else for(let[n,a]of l.preStyleMap.entries())n.tagName!=="STYLE"&&n.setAttribute("style",a.replace(/;/g,"; "));for(let[n,a]of l.preNodeMap.entries()){let i=a.scrollLeft,d=a.scrollTop;if((i||d)&&n instanceof HTMLElement){n.style.overflow="hidden",n.style.scrollbarWidth="none",n.style.msOverflowStyle="none";let f=document.createElement("div");for(f.style.transform=`translate(${-i}px, ${-d}px)`,f.style.willChange="transform",f.style.display="inline-block",f.style.width="100%";n.firstChild;)f.appendChild(n.firstChild);n.appendChild(f)}}if(e===l.preNodeMap.get(s)){let n=l.preStyle.get(e)||window.getComputedStyle(e);l.preStyle.set(e,n);let a=pe(n.transform);s.style.margin="0",s.style.position="static",s.style.top="auto",s.style.left="auto",s.style.right="auto",s.style.bottom="auto",s.style.zIndex="auto",s.style.float="none",s.style.clear="none",s.style.transform=a||""}for(let[n,a]of l.preNodeMap.entries())a.tagName==="PRE"&&(n.style.marginTop="0",n.style.marginBlockStart="0");return{clone:s,classCSS:o}}function Pe(e){let t=getComputedStyle(e),r=t.outlineStyle,c=t.outlineWidth,s=t.borderStyle,o=t.borderWidth,n=r!=="none"&&parseFloat(c)>0,a=s==="none"||parseFloat(o)===0;n&&a&&(e.style.border=`${c} solid transparent`)}async function Se(e,t={}){let r=Array.from(e.querySelectorAll("img")),c=async s=>{let o=s.src;try{let n=await M(o,{useProxy:t.useProxy});s.src=n,s.width||(s.width=s.naturalWidth||100),s.height||(s.height=s.naturalHeight||100)}catch{let n=document.createElement("div");n.style=`width: ${s.width||100}px; height: ${s.height||100}px; background: #ccc; display: inline-block; text-align: center; line-height: ${s.height||100}px; color: #666; font-size: 12px;`,n.innerText="img",s.replaceWith(n)}};for(let s=0;s<r.length;s+=4){let o=r.slice(s,s+4).map(c);await Promise.allSettled(o)}}async function xe(e,t,r={}){let c=[[e,t]],s=["background-image","mask","mask-image","-webkit-mask-image","mask-source","mask-box-image-source","mask-border-source","-webkit-mask-box-image-source","border-image","border-image-source","border-image-slice","border-image-width","border-image-outset","border-image-repeat"];for(;c.length;){let[o,n]=c.shift(),a=l.preStyle.get(o)||I(o);l.preStyle.has(o)||l.preStyle.set(o,a);let i=(()=>{let m=a.getPropertyValue("border-image"),p=a.getPropertyValue("border-image-source");return m&&m!=="none"||p&&p!=="none"})();for(let m of s){if(["border-image-slice","border-image-width","border-image-outset","border-image-repeat"].includes(m)&&!i)continue;let p=a.getPropertyValue(m);if(!p||p==="none")continue;let h=U(p),y=await Promise.all(h.map(w=>P(w,r)));y.some(w=>w&&w!=="none"&&!/^url\(undefined/.test(w))&&n.style.setProperty(m,y.join(", "))}let d=a.getPropertyValue("background-color");d&&d!=="transparent"&&d!=="rgba(0, 0, 0, 0)"&&(n.style.backgroundColor=d);let u=Array.from(o.children),f=Array.from(n.children);for(let m=0;m<Math.min(u.length,f.length);m++)c.push([u[m],f[m]])}}async function Ce(e,t={}){if(!e)throw new Error("Element cannot be null or undefined");l.reset();let{compress:r=!0,embedFonts:c=!1,fast:s=!0,scale:o=1,useProxy:n=""}=t,a,i,d="",u="",f,m;if({clone:a,classCSS:i}=await be(e,r,c,t),await new Promise(h=>{F(async()=>{await Se(a,t),h()},{fast:s})}),await new Promise(h=>{F(async()=>{await xe(e,a,t),h()},{fast:s})}),c&&await new Promise(h=>{F(async()=>{d=await K(),h()},{fast:s})}),r){let h=le(a).sort(),y=h.join(",");l.baseStyle.has(y)?u=l.baseStyle.get(y):await new Promise(w=>{F(()=>{u=de(h),l.baseStyle.set(y,u),w()},{fast:s})})}await new Promise(h=>{F(()=>{let y=e.getBoundingClientRect(),w=y.width,g=y.height,E=Number.isFinite(t.width),$=Number.isFinite(t.height),R=typeof o=="number"&&o!==1;if(!R){let A=y.width/y.height;E&&$?(w=t.width,g=t.height):E?(w=t.width,g=w/A):$&&(g=t.height,w=g*A)}if(w=Math.ceil(w),g=Math.ceil(g),a.setAttribute("xmlns","http://www.w3.org/1999/xhtml"),a.style.transformOrigin="top left",!R&&(E||$)){let A=y.width,oe=y.height,S=w/A,X=g/oe,J=a.style.transform||"",re=`scale(${S}, ${X})`;a.style.transform=`${re} ${J}`.trim()}let N="http://www.w3.org/2000/svg",x=document.createElementNS(N,"foreignObject");x.setAttribute("width","100%"),x.setAttribute("height","100%");let B=document.createElement("style");B.textContent=u+d+"svg{overflow:visible;}"+i,x.appendChild(B),x.appendChild(a);let W=new XMLSerializer().serializeToString(x);m=`<svg xmlns="${N}" width="${w}" height="${g}" viewBox="0 0 ${w} ${g}">`+W+"</svg>",f=`data:image/svg+xml;charset=utf-8,${encodeURIComponent(m)}`,h()},{fast:s})});let p=document.getElementById("snapdom-sandbox");return p&&p.style.position==="absolute"&&p.remove(),f}async function Fe(e,{scale:t=1}={}){let r=new Image;return r.src=e,await r.decode(),t!==1&&(r.style.width=`${r.naturalWidth*t}px`,r.style.height=`${r.naturalHeight*t}px`),r}async function Ee(e,{dpr:t=1,scale:r=1}={}){let c=new Image;c.src=e,c.crossOrigin="anonymous",c.loading="eager",c.decoding="sync";let s=me(),o=!1;if(s&&(document.body.appendChild(c),o=!0),await c.decode(),s&&await new Promise(u=>setTimeout(u,100)),c.width===0||c.height===0)throw o&&c.remove(),new Error("Image failed to load or has no dimensions");let n=c.naturalWidth*r,a=c.naturalHeight*r,i=document.createElement("canvas");i.width=Math.ceil(n*t),i.height=Math.ceil(a*t),i.style.width=`${n}px`,i.style.height=`${a}px`;let d=i.getContext("2d");return d.scale(t,t),d.drawImage(c,0,0,n,a),o&&c.remove(),i}async function ve(e,{type:t="svg",scale:r=1,backgroundColor:c="#fff",quality:s}={}){let o={jpg:"image/jpeg",jpeg:"image/jpeg",png:"image/png",webp:"image/webp"}[t]||"image/png";if(t==="svg"){let a=decodeURIComponent(e.split(",")[1]);return new Blob([a],{type:"image/svg+xml"})}let n=await ne(e,{dpr:1,scale:r},c);return new Promise(a=>{n.toBlob(i=>a(i),`${o}`,s)})}async function ne(e,{dpr:t=1,scale:r=1},c){let s=await Ee(e,{dpr:t,scale:r});if(!c)return s;let o=document.createElement("canvas");o.width=s.width,o.height=s.height;let n=o.getContext("2d");return n.fillStyle=c,n.fillRect(0,0,o.width,o.height),n.drawImage(s,0,0),o}async function te(e,{dpr:t=1,scale:r=1,backgroundColor:c,quality:s},o="png"){let n=["jpg","jpeg","webp"].includes(o)?"#fff":void 0,i=await ne(e,{dpr:t,scale:r},c??n),d=new Image;return d.src=i.toDataURL(`image/${o}`,s),await d.decode(),d.style.width=`${i.width/t}px`,d.style.height=`${i.height/t}px`,d}async function Ue(e,{dpr:t=1,scale:r=1,backgroundColor:c,format:s="png",filename:o="snapDOM"}={}){if(s==="svg"){let m=await ve(e),p=URL.createObjectURL(m),h=document.createElement("a");h.href=p,h.download=`${o}.svg`,h.click(),URL.revokeObjectURL(p);return}let n=["jpg","jpeg","webp"].includes(s)?"#fff":void 0,i=await ne(e,{dpr:t,scale:r},c??n),d={jpg:"image/jpeg",jpeg:"image/jpeg",png:"image/png",webp:"image/webp"}[s]||"image/png",u=i.toDataURL(d),f=document.createElement("a");f.href=u,f.download=`${o}.${s}`,f.click()}async function b(e,t={}){if(t={scale:1,...t},!e)throw new Error("Element cannot be null or undefined");return t.iconFonts&&he(t.iconFonts),await b.capture(e,t)}b.capture=async(e,t={})=>{let r=await Ce(e,t),c=t.dpr??(window.devicePixelRatio||1),s=t.scale||1;return{url:r,options:t,toRaw:()=>r,toImg:(o={})=>Fe(r,{dpr:c,scale:s,...o}),toCanvas:(o={})=>Ee(r,{dpr:c,scale:s,...o}),toBlob:(o={})=>ve(r,{dpr:c,scale:s,...o}),toPng:(o={})=>te(r,{dpr:c,scale:s,...o},"png"),toJpg:(o={})=>te(r,{dpr:c,scale:s,...o},"jpeg"),toWebp:(o={})=>te(r,{dpr:c,scale:s,...o},"webp"),download:({format:o="png",filename:n="snapDOM",backgroundColor:a,...i}={})=>Ue(r,{dpr:c,scale:s,format:o,filename:n,backgroundColor:a,...i})}};b.toRaw=async(e,t)=>(await b.capture(e,t)).toRaw();b.toImg=async(e,t)=>(await b.capture(e,t)).toImg();b.toCanvas=async(e,t)=>(await b.capture(e,t)).toCanvas();b.toBlob=async(e,t)=>(await b.capture(e,t)).toBlob(t);b.toPng=async(e,t)=>(await b.capture(e,t)).toPng(t);b.toJpg=async(e,t)=>(await b.capture(e,t)).toJpg(t);b.toWebp=async(e,t)=>(await b.capture(e,t)).toWebp(t);b.download=async(e,t={})=>{let{format:r="png",filename:c="capture",backgroundColor:s,...o}=t;return await(await b.capture(e,o)).download({format:r,filename:c,backgroundColor:s})};async function Be(e=document,t={}){let{embedFonts:r=!0,reset:c=!1}=t;if(c){l.reset();return}await document.fonts.ready,ie();let s=[],o=[];e?.querySelectorAll&&(s=Array.from(e.querySelectorAll("img[src]")),o=Array.from(e.querySelectorAll("*")));let n=[];for(let a of s){let i=a.src;l.image.has(i)||n.push(M(i,{useProxy:t.useProxy}).then(d=>l.image.set(i,d)).catch(()=>{}))}for(let a of o){let i=I(a).backgroundImage;if(i&&i!=="none"){let d=U(i);for(let u of d)u.startsWith("url(")&&n.push(P(u,t).catch(()=>{}))}}r&&await K({preCached:!0}),await Promise.all(n)}export{Be as preCache,b as snapdom};
@@ -43,6 +43,18 @@ class UmapManifestStaticFilesStorage(ManifestStaticFilesStorage):
43
43
  ),
44
44
  )
45
45
 
46
+ patterns = ManifestStaticFilesStorage.patterns + (
47
+ (
48
+ "*.svg",
49
+ (
50
+ (
51
+ r'(?P<matched>xlink:href="(?P<url>.*\.js)")',
52
+ 'xlink:href="%(url)s"',
53
+ ),
54
+ ),
55
+ ),
56
+ )
57
+
46
58
  def post_process(self, paths, **options):
47
59
  collected = super().post_process(paths, **options)
48
60
  for original_path, processed_path, processed in collected:
@@ -4,10 +4,6 @@
4
4
 
5
5
  <link rel="stylesheet"
6
6
  href="{% static 'umap/vendors/leaflet/leaflet.css' %}" />
7
- <link rel="stylesheet"
8
- href="{% static 'umap/vendors/markercluster/MarkerCluster.css' %}" />
9
- <link rel="stylesheet"
10
- href="{% static 'umap/vendors/markercluster/MarkerCluster.Default.css' %}" />
11
7
  <link rel="stylesheet"
12
8
  href="{% static 'umap/vendors/editinosm/Leaflet.EditInOSM.css' %}" />
13
9
  <link rel="stylesheet"
@@ -7,17 +7,15 @@
7
7
  <script type="module"
8
8
  src="{% static 'umap/js/modules/leaflet-configure.js' %}"
9
9
  defer></script>
10
- <script src="{% static 'umap/vendors/markercluster/leaflet.markercluster.js' %}"
11
- defer></script>
12
10
  <script src="{% static 'umap/vendors/heat/leaflet-heat.js' %}" defer></script>
13
11
  {% if locale %}
14
12
  {% with "umap/locale/"|add:locale|add:".js" as path %}
15
13
  <script src="{% static path %}" defer></script>
16
14
  {% endwith %}
17
15
  {% endif %}
18
- <script type="module" src="{% static 'umap/js/modules/global.js' %}" defer></script>
19
16
  <script src="{% static 'umap/vendors/editable/Path.Drag.js' %}" defer></script>
20
17
  <script src="{% static 'umap/vendors/editable/Leaflet.Editable.js' %}" defer></script>
18
+ <script type="module" src="{% static 'umap/js/modules/global.js' %}" defer></script>
21
19
  <script src="{% static 'umap/vendors/hash/leaflet-hash.js' %}" defer></script>
22
20
  <script src="{% static 'umap/vendors/editinosm/Leaflet.EditInOSM.js' %}"
23
21
  defer></script>
@@ -42,6 +42,8 @@ def test_create_map_with_cursor(page, live_server, tilelayer):
42
42
  (
43
43
  "margin-left: -16px; "
44
44
  "margin-top: -40px; "
45
+ "width: 12px; "
46
+ "height: 12px; "
45
47
  "transform: translate3d(200px, 200px, 0px); "
46
48
  "z-index: 0;"
47
49
  ),
@@ -103,7 +103,7 @@ def test_simple_equal_rule_at_load(live_server, page, map):
103
103
  DataLayerFactory(map=map, data=DATALAYER_DATA1)
104
104
  DataLayerFactory(map=map, data=DATALAYER_DATA2)
105
105
  page.goto(f"{live_server.url}{map.get_absolute_url()}#6/48.948/1.670")
106
- markers = page.locator(".leaflet-marker-icon .icon_container")
106
+ markers = page.locator(".leaflet-marker-icon .icon-container")
107
107
  expect(markers).to_have_count(5)
108
108
  colors = getColors(markers)
109
109
  assert colors.count("rgb(240, 248, 255)") == 3
@@ -117,7 +117,7 @@ def test_simple_not_equal_rule_at_load(live_server, page, map):
117
117
  DataLayerFactory(map=map, data=DATALAYER_DATA1)
118
118
  DataLayerFactory(map=map, data=DATALAYER_DATA2)
119
119
  page.goto(f"{live_server.url}{map.get_absolute_url()}#6/48.948/1.670")
120
- markers = page.locator(".leaflet-marker-icon .icon_container")
120
+ markers = page.locator(".leaflet-marker-icon .icon-container")
121
121
  expect(markers).to_have_count(5)
122
122
  colors = getColors(markers)
123
123
  assert colors.count("rgb(240, 248, 255)") == 3
@@ -131,7 +131,7 @@ def test_gt_rule_with_number_at_load(live_server, page, map):
131
131
  DataLayerFactory(map=map, data=DATALAYER_DATA1)
132
132
  DataLayerFactory(map=map, data=DATALAYER_DATA2)
133
133
  page.goto(f"{live_server.url}{map.get_absolute_url()}#6/48.948/1.670")
134
- markers = page.locator(".leaflet-marker-icon .icon_container")
134
+ markers = page.locator(".leaflet-marker-icon .icon-container")
135
135
  expect(markers).to_have_count(5)
136
136
  colors = getColors(markers)
137
137
  assert colors.count("rgb(240, 248, 255)") == 2
@@ -145,7 +145,7 @@ def test_lt_rule_with_number_at_load(live_server, page, map):
145
145
  DataLayerFactory(map=map, data=DATALAYER_DATA1)
146
146
  DataLayerFactory(map=map, data=DATALAYER_DATA2)
147
147
  page.goto(f"{live_server.url}{map.get_absolute_url()}#6/48.948/1.670")
148
- markers = page.locator(".leaflet-marker-icon .icon_container")
148
+ markers = page.locator(".leaflet-marker-icon .icon-container")
149
149
  expect(markers).to_have_count(5)
150
150
  colors = getColors(markers)
151
151
  assert colors.count("rgb(240, 248, 255)") == 4
@@ -159,7 +159,7 @@ def test_lt_rule_with_float_at_load(live_server, page, map):
159
159
  DataLayerFactory(map=map, data=DATALAYER_DATA1)
160
160
  DataLayerFactory(map=map, data=DATALAYER_DATA2)
161
161
  page.goto(f"{live_server.url}{map.get_absolute_url()}#6/48.948/1.670")
162
- markers = page.locator(".leaflet-marker-icon .icon_container")
162
+ markers = page.locator(".leaflet-marker-icon .icon-container")
163
163
  expect(markers).to_have_count(5)
164
164
  colors = getColors(markers)
165
165
  assert colors.count("rgb(240, 248, 255)") == 4
@@ -173,7 +173,7 @@ def test_equal_rule_with_boolean_at_load(live_server, page, map):
173
173
  DataLayerFactory(map=map, data=DATALAYER_DATA1)
174
174
  DataLayerFactory(map=map, data=DATALAYER_DATA2)
175
175
  page.goto(f"{live_server.url}{map.get_absolute_url()}#6/48.948/1.670")
176
- markers = page.locator(".leaflet-marker-icon .icon_container")
176
+ markers = page.locator(".leaflet-marker-icon .icon-container")
177
177
  expect(markers).to_have_count(5)
178
178
  colors = getColors(markers)
179
179
  assert colors.count("rgb(240, 248, 255)") == 2
@@ -187,7 +187,7 @@ def test_equal_rule_with_boolean_not_true_at_load(live_server, page, map):
187
187
  DataLayerFactory(map=map, data=DATALAYER_DATA1)
188
188
  DataLayerFactory(map=map, data=DATALAYER_DATA2)
189
189
  page.goto(f"{live_server.url}{map.get_absolute_url()}#6/48.948/1.670")
190
- markers = page.locator(".leaflet-marker-icon .icon_container")
190
+ markers = page.locator(".leaflet-marker-icon .icon-container")
191
191
  expect(markers).to_have_count(5)
192
192
  colors = getColors(markers)
193
193
  assert colors.count("rgb(240, 248, 255)") == 3
@@ -201,7 +201,7 @@ def test_equal_rule_with_boolean_false_at_load(live_server, page, map):
201
201
  DataLayerFactory(map=map, data=DATALAYER_DATA1)
202
202
  DataLayerFactory(map=map, data=DATALAYER_DATA2)
203
203
  page.goto(f"{live_server.url}{map.get_absolute_url()}#6/48.948/1.670")
204
- markers = page.locator(".leaflet-marker-icon .icon_container")
204
+ markers = page.locator(".leaflet-marker-icon .icon-container")
205
205
  expect(markers).to_have_count(5)
206
206
  colors = getColors(markers)
207
207
  assert colors.count("rgb(240, 248, 255)") == 1
@@ -215,7 +215,7 @@ def test_equal_rule_with_boolean_not_false_at_load(live_server, page, map):
215
215
  DataLayerFactory(map=map, data=DATALAYER_DATA1)
216
216
  DataLayerFactory(map=map, data=DATALAYER_DATA2)
217
217
  page.goto(f"{live_server.url}{map.get_absolute_url()}#6/48.948/1.670")
218
- markers = page.locator(".leaflet-marker-icon .icon_container")
218
+ markers = page.locator(".leaflet-marker-icon .icon-container")
219
219
  expect(markers).to_have_count(5)
220
220
  colors = getColors(markers)
221
221
  assert colors.count("rgb(240, 248, 255)") == 4
@@ -229,7 +229,7 @@ def test_empty_rule_at_load(live_server, page, map):
229
229
  DataLayerFactory(map=map, data=DATALAYER_DATA1)
230
230
  DataLayerFactory(map=map, data=DATALAYER_DATA2)
231
231
  page.goto(f"{live_server.url}{map.get_absolute_url()}#6/48.948/1.670")
232
- markers = page.locator(".leaflet-marker-icon .icon_container")
232
+ markers = page.locator(".leaflet-marker-icon .icon-container")
233
233
  expect(markers).to_have_count(5)
234
234
  colors = getColors(markers)
235
235
  assert colors.count("rgb(240, 248, 255)") == 3
@@ -243,7 +243,7 @@ def test_not_empty_rule_at_load(live_server, page, map):
243
243
  DataLayerFactory(map=map, data=DATALAYER_DATA1)
244
244
  DataLayerFactory(map=map, data=DATALAYER_DATA2)
245
245
  page.goto(f"{live_server.url}{map.get_absolute_url()}#6/48.948/1.670")
246
- markers = page.locator(".leaflet-marker-icon .icon_container")
246
+ markers = page.locator(".leaflet-marker-icon .icon-container")
247
247
  expect(markers).to_have_count(5)
248
248
  colors = getColors(markers)
249
249
  assert colors.count("rgb(240, 248, 255)") == 2
@@ -253,7 +253,7 @@ def test_can_create_new_rule(live_server, page, openmap):
253
253
  DataLayerFactory(map=openmap, data=DATALAYER_DATA1)
254
254
  DataLayerFactory(map=openmap, data=DATALAYER_DATA2)
255
255
  page.goto(f"{live_server.url}{openmap.get_absolute_url()}#6/48.948/1.670")
256
- markers = page.locator(".leaflet-marker-icon .icon_container")
256
+ markers = page.locator(".leaflet-marker-icon .icon-container")
257
257
  expect(markers).to_have_count(5)
258
258
  page.get_by_role("button", name="Edit").click()
259
259
  page.get_by_role("button", name="Map advanced properties").click()
@@ -278,7 +278,7 @@ def test_can_deactive_rule_from_list(live_server, page, openmap):
278
278
  DataLayerFactory(map=openmap, data=DATALAYER_DATA1)
279
279
  DataLayerFactory(map=openmap, data=DATALAYER_DATA2)
280
280
  page.goto(f"{live_server.url}{openmap.get_absolute_url()}#6/48.948/1.670")
281
- markers = page.locator(".leaflet-marker-icon .icon_container")
281
+ markers = page.locator(".leaflet-marker-icon .icon-container")
282
282
  expect(markers).to_have_count(5)
283
283
  colors = getColors(markers)
284
284
  assert colors.count("rgb(240, 248, 255)") == 3
@@ -331,8 +331,8 @@ def test_can_combine_rules(live_server, page, map):
331
331
  DataLayerFactory(map=map, data=DATALAYER_DATA1)
332
332
  DataLayerFactory(map=map, data=DATALAYER_DATA2)
333
333
  page.goto(f"{live_server.url}{map.get_absolute_url()}#6/48.948/1.670")
334
- markers = page.locator(".leaflet-marker-icon .icon_container")
335
- drops = page.locator(".umap-drop-icon .icon_container")
334
+ markers = page.locator(".leaflet-marker-icon .icon-container")
335
+ drops = page.locator(".umap-drop-icon .icon-container")
336
336
  expect(markers).to_have_count(5)
337
337
  expect(drops).to_have_count(2)
338
338
  colors = getColors(markers)
@@ -350,7 +350,7 @@ def test_first_matching_rule_wins_on_given_property(live_server, page, map):
350
350
  DataLayerFactory(map=map, data=DATALAYER_DATA1)
351
351
  DataLayerFactory(map=map, data=DATALAYER_DATA2)
352
352
  page.goto(f"{live_server.url}{map.get_absolute_url()}#6/48.948/1.670")
353
- markers = page.locator(".leaflet-marker-icon .icon_container")
353
+ markers = page.locator(".leaflet-marker-icon .icon-container")
354
354
  expect(markers).to_have_count(5)
355
355
  colors = getColors(markers)
356
356
  assert colors.count("rgb(240, 248, 255)") == 3
@@ -368,7 +368,7 @@ def test_rules_from_datalayer(live_server, page, map):
368
368
  DataLayerFactory(map=map, data=data)
369
369
  DataLayerFactory(map=map, data=DATALAYER_DATA2)
370
370
  page.goto(f"{live_server.url}{map.get_absolute_url()}#6/48.948/1.670")
371
- markers = page.locator(".leaflet-marker-icon .icon_container")
371
+ markers = page.locator(".leaflet-marker-icon .icon-container")
372
372
  expect(markers).to_have_count(5)
373
373
  colors = getColors(markers)
374
374
  # Alice Blue should only affect layer 1
@@ -115,7 +115,7 @@ def test_should_honour_color_variable(live_server, map, page):
115
115
  DataLayerFactory(map=map, data=data)
116
116
  page.goto(f"{live_server.url}{map.get_absolute_url()}#6/47.5/2.5")
117
117
  expect(page.locator(".leaflet-overlay-pane path[fill='tomato']"))
118
- markers = page.locator(".leaflet-marker-icon .icon_container")
118
+ markers = page.locator(".leaflet-marker-icon .icon-container")
119
119
  expect(markers).to_have_css("background-color", "rgb(240, 248, 255)")
120
120
 
121
121
 
@@ -154,9 +154,7 @@ def test_can_draw_multi(live_server, page, tilelayer):
154
154
  expect(multi_button).to_be_hidden()
155
155
  polygons.first.click(button="right", position={"x": 10, "y": 10})
156
156
  expect(page.get_by_role("button", name="Transform to lines")).to_be_hidden()
157
- expect(
158
- page.get_by_role("button", name="Remove shape from the multi")
159
- ).to_be_visible()
157
+ expect(page.get_by_role("button", name="Delete this shape")).to_be_visible()
160
158
 
161
159
 
162
160
  def test_can_draw_hole(page, live_server, tilelayer):
@@ -179,7 +177,7 @@ def test_can_draw_hole(page, live_server, tilelayer):
179
177
  expect(vertices).to_have_count(4)
180
178
 
181
179
  # First vertex of the hole will be created here
182
- map.click(position={"x": 180, "y": 120})
180
+ map.click(position={"x": 180, "y": 120}, button="right")
183
181
  page.get_by_role("button", name="Start a hole here").click()
184
182
  map.click(position={"x": 180, "y": 180})
185
183
  map.click(position={"x": 120, "y": 180})
@@ -474,7 +472,7 @@ def test_vertexmarker_not_shown_if_too_many(live_server, map, page, settings):
474
472
  page.locator(".umap-import textarea").fill(geojson)
475
473
  page.locator('select[name="format"]').select_option("geojson")
476
474
  page.get_by_role("button", name="Import data", exact=True).click()
477
- page.locator("path").click()
475
+ page.locator("path").click(button="right")
478
476
  page.get_by_role("button", name="Toggle edit mode (⇧+Click)").click()
479
477
  expect(page.locator(".umap-tooltip-container")).to_contain_text(
480
478
  "Please zoom in to edit the geometry"
@@ -150,9 +150,7 @@ def test_can_draw_multi(live_server, page, tilelayer):
150
150
  expect(add_shape).to_be_hidden()
151
151
  lines.first.click(button="right", position={"x": 10, "y": 1})
152
152
  expect(page.get_by_role("button", name="Transform to polygon")).to_be_hidden()
153
- expect(
154
- page.get_by_role("button", name="Remove shape from the multi")
155
- ).to_be_visible()
153
+ expect(page.get_by_role("button", name="Delete this shape")).to_be_visible()
156
154
 
157
155
 
158
156
  def test_can_transfer_shape_from_simple_polyline(live_server, page, tilelayer):
@@ -328,11 +326,11 @@ def test_can_delete_shape_using_toolbar(live_server, page, tilelayer, settings):
328
326
  map.click(position={"x": 100, "y": 200})
329
327
 
330
328
  # Now split the line
331
- map.click(position={"x": 100, "y": 100})
329
+ map.click(position={"x": 100, "y": 100}, button="right")
332
330
  page.get_by_role("button", name="Split line").click()
333
331
 
334
332
  # Delete part of it
335
- map.click(position={"x": 125, "y": 100})
333
+ map.click(position={"x": 125, "y": 100}, button="right")
336
334
  page.get_by_role("button", name="Delete this shape").click()
337
335
  data = save_and_get_json(page)
338
336
  assert len(data["features"]) == 1
@@ -369,7 +367,7 @@ def test_can_merge_lines(live_server, page, tilelayer, settings):
369
367
  )
370
368
 
371
369
  # Right click and merge nodes
372
- map.click(button="right", position={"x": 100, "y": 200})
370
+ map.click(button="right", position={"x": 100, "y": 120})
373
371
  page.get_by_role("button", name="Merge lines").click()
374
372
  data = save_and_get_json(page)
375
373
  assert len(data["features"]) == 1
@@ -0,0 +1,178 @@
1
+ import pytest
2
+ from playwright.sync_api import expect
3
+
4
+ pytestmark = pytest.mark.django_db
5
+
6
+
7
+ def test_route_button_is_hidden(page, live_server, tilelayer, settings):
8
+ page.goto(f"{live_server.url}/en/map/new/#14/47.7591/2.4134")
9
+ expect(page.get_by_role("button", name="Draw along routes")).to_be_hidden()
10
+
11
+
12
+ def test_draw_route(page, live_server, tilelayer, settings):
13
+ settings.OPENROUTESERVICE_APIKEY = "FOOBAR="
14
+ cycling_response = {
15
+ "type": "FeatureCollection",
16
+ "bbox": [2.367278, 47.768019, 2.375744, 47.774736],
17
+ "features": [
18
+ {
19
+ "bbox": [2.367278, 47.768019, 2.375744, 47.774736],
20
+ "type": "Feature",
21
+ "properties": {
22
+ "way_points": [0, 31],
23
+ "summary": {"distance": 1228.2, "duration": 308.4},
24
+ },
25
+ "geometry": {
26
+ "coordinates": [
27
+ [2.367419, 47.77416],
28
+ [2.367278, 47.774736],
29
+ [2.367914, 47.774734],
30
+ [2.367982, 47.774676],
31
+ [2.368261, 47.774569],
32
+ [2.368397, 47.774488],
33
+ [2.368517, 47.774396],
34
+ [2.368745, 47.77417],
35
+ [2.368963, 47.773917],
36
+ [2.369246, 47.773728],
37
+ [2.369376, 47.773669],
38
+ [2.37024, 47.773401],
39
+ [2.370303, 47.773393],
40
+ [2.370277, 47.7733],
41
+ [2.37047, 47.77325],
42
+ [2.371473, 47.772904],
43
+ [2.371666, 47.772883],
44
+ [2.371669, 47.772587],
45
+ [2.37161, 47.772529],
46
+ [2.371584, 47.772466],
47
+ [2.371589, 47.772401],
48
+ [2.371672, 47.772301],
49
+ [2.371801, 47.77225],
50
+ [2.371875, 47.772172],
51
+ [2.371966, 47.771983],
52
+ [2.372052, 47.77171],
53
+ [2.373877, 47.768035],
54
+ [2.374129, 47.768118],
55
+ [2.374149, 47.768088],
56
+ [2.374132, 47.768019],
57
+ [2.375642, 47.768538],
58
+ [2.375744, 47.768386],
59
+ ],
60
+ "type": "LineString",
61
+ },
62
+ }
63
+ ],
64
+ "metadata": {
65
+ "attribution": "openrouteservice.org | OpenStreetMap contributors",
66
+ "service": "routing",
67
+ "timestamp": 1753716213909,
68
+ "query": {
69
+ "coordinates": [[2.367039, 47.774118], [2.375622, 47.768349]],
70
+ "profile": "cycling-regular",
71
+ "profileName": "cycling-regular",
72
+ "preference": "recommended",
73
+ "format": "geojson",
74
+ "geometry_simplify": True,
75
+ },
76
+ "engine": {
77
+ "version": "9.3.0",
78
+ "build_date": "2025-06-06T15:39:25Z",
79
+ "graph_date": "2025-06-22T07:54:02Z",
80
+ "osm_date": "1970-01-01T00:00:00Z",
81
+ },
82
+ },
83
+ }
84
+
85
+ car_response = {
86
+ "type": "FeatureCollection",
87
+ "bbox": [2.367278, 47.768035, 2.375458, 47.774736],
88
+ "features": [
89
+ {
90
+ "bbox": [2.367278, 47.768035, 2.375458, 47.774736],
91
+ "type": "Feature",
92
+ "properties": {
93
+ "way_points": [0, 17],
94
+ "summary": {"distance": 1283.8, "duration": 160.8},
95
+ },
96
+ "geometry": {
97
+ "coordinates": [
98
+ [2.367419, 47.77416],
99
+ [2.367278, 47.774736],
100
+ [2.367476, 47.774736],
101
+ [2.367495, 47.774429],
102
+ [2.367601, 47.773963],
103
+ [2.367799, 47.773307],
104
+ [2.368261, 47.772056],
105
+ [2.370046, 47.772198],
106
+ [2.371213, 47.772406],
107
+ [2.371469, 47.772383],
108
+ [2.371625, 47.772341],
109
+ [2.371672, 47.772301],
110
+ [2.371801, 47.77225],
111
+ [2.371875, 47.772172],
112
+ [2.371966, 47.771983],
113
+ [2.372052, 47.77171],
114
+ [2.373877, 47.768035],
115
+ [2.375458, 47.768569],
116
+ ],
117
+ "type": "LineString",
118
+ },
119
+ }
120
+ ],
121
+ "metadata": {
122
+ "attribution": "openrouteservice.org | OpenStreetMap contributors",
123
+ "service": "routing",
124
+ "timestamp": 1753717466321,
125
+ "query": {
126
+ "coordinates": [[2.367039, 47.774118], [2.375622, 47.768349]],
127
+ "profile": "driving-car",
128
+ "profileName": "driving-car",
129
+ "preference": "recommended",
130
+ "format": "geojson",
131
+ "geometry_simplify": True,
132
+ },
133
+ "engine": {
134
+ "version": "9.3.0",
135
+ "build_date": "2025-06-06T15:39:25Z",
136
+ "graph_date": "2025-06-23T11:47:36Z",
137
+ "osm_date": "1970-01-01T00:00:00Z",
138
+ },
139
+ },
140
+ }
141
+
142
+ def handle_cycling(route):
143
+ route.fulfill(json=cycling_response)
144
+
145
+ def handle_car(route):
146
+ route.fulfill(json=car_response)
147
+
148
+ # Intercept the route
149
+ page.route(
150
+ "https://api.openrouteservice.org/v2/directions/cycling-regular/geojson",
151
+ handle_cycling,
152
+ )
153
+ page.route(
154
+ "https://api.openrouteservice.org/v2/directions/driving-car/geojson",
155
+ handle_car,
156
+ )
157
+ page.goto(f"{live_server.url}/en/map/new/#14/47.7591/2.4134")
158
+ expect(page.locator("path")).to_be_hidden()
159
+ expect(page.locator(".leaflet-vertex-icon")).to_be_hidden()
160
+ page.get_by_role("button", name="Draw along routes").click()
161
+ page.locator('select[name="profile"]').select_option("cycling-regular")
162
+ page.get_by_role("button", name="OK").click()
163
+ page.locator("#map").click(position={"x": 100, "y": 100})
164
+ page.locator("#map").click(position={"x": 200, "y": 200})
165
+ page.locator("#map").click(position={"x": 200, "y": 200})
166
+ expect(page.locator("path")).to_be_visible()
167
+ expect(page.locator(".leaflet-vertex-icon")).to_have_count(2)
168
+ page.get_by_text("Advanced actions").click()
169
+ page.get_by_role("button", name="Transform to regular line").click()
170
+ expect(page.locator(".leaflet-vertex-icon")).to_have_count(32)
171
+ page.get_by_text("Advanced actions").click()
172
+ page.get_by_role("button", name="Restore route").click()
173
+ expect(page.locator(".leaflet-vertex-icon")).to_have_count(2)
174
+ page.locator('#edit-route select[name="profile"]').select_option("driving-car")
175
+ page.get_by_role("button", name="Compute route").click()
176
+ page.get_by_text("Advanced actions").click()
177
+ page.get_by_role("button", name="Transform to regular line").click()
178
+ expect(page.locator(".leaflet-vertex-icon")).to_have_count(18)
@@ -99,7 +99,7 @@ def test_map_color_impacts_data(live_server, page, tilelayer):
99
99
  page.get_by_title("Lime", exact=True).click()
100
100
 
101
101
  # Assert the new color was used
102
- marker_style = page.locator(".leaflet-marker-icon .icon_container").get_attribute(
102
+ marker_style = page.locator(".leaflet-marker-icon .icon-container").get_attribute(
103
103
  "style"
104
104
  )
105
105
  assert "lime" in marker_style
@@ -47,11 +47,11 @@ def test_marker_style_should_have_precedence(live_server, openmap, page, bootstr
47
47
  page.locator(".panel").get_by_title("Edit", exact=True).click()
48
48
  page.get_by_text("Shape properties").click()
49
49
  page.locator(".umap-field-color .define").click()
50
- expect(page.locator(".leaflet-marker-icon .icon_container")).to_have_css(
50
+ expect(page.locator(".leaflet-marker-icon .icon-container")).to_have_css(
51
51
  "background-color", "rgb(0, 0, 139)"
52
52
  )
53
53
  page.get_by_title("DarkRed").first.click()
54
- expect(page.locator(".leaflet-marker-icon .icon_container")).to_have_css(
54
+ expect(page.locator(".leaflet-marker-icon .icon-container")).to_have_css(
55
55
  "background-color", "rgb(139, 0, 0)"
56
56
  )
57
57
 
@@ -60,7 +60,7 @@ def test_marker_style_should_have_precedence(live_server, openmap, page, bootstr
60
60
  page.get_by_text("Shape properties").click()
61
61
  page.locator("#umap-feature-shape-properties").get_by_text("define").first.click()
62
62
  page.get_by_title("GoldenRod", exact=True).click()
63
- expect(page.locator(".leaflet-marker-icon .icon_container")).to_have_css(
63
+ expect(page.locator(".leaflet-marker-icon .icon-container")).to_have_css(
64
64
  "background-color", "rgb(218, 165, 32)"
65
65
  )
66
66
 
@@ -70,14 +70,14 @@ def test_marker_style_should_have_precedence(live_server, openmap, page, bootstr
70
70
  page.get_by_text("Shape properties").click()
71
71
  page.locator(".umap-field-color input").click()
72
72
  page.get_by_title("DarkViolet").first.click()
73
- expect(page.locator(".leaflet-marker-icon .icon_container")).to_have_css(
73
+ expect(page.locator(".leaflet-marker-icon .icon-container")).to_have_css(
74
74
  "background-color", "rgb(218, 165, 32)"
75
75
  )
76
76
 
77
77
 
78
78
  def test_should_open_an_edit_toolbar_on_click(live_server, openmap, page, bootstrap):
79
79
  page.goto(f"{live_server.url}{openmap.get_absolute_url()}?edit")
80
- page.locator(".leaflet-marker-icon").click()
80
+ page.locator(".leaflet-marker-icon").click(button="right")
81
81
  expect(page.get_by_role("button", name="Toggle edit mode")).to_be_visible()
82
82
  expect(page.get_by_role("button", name="Delete this feature")).to_be_visible()
83
83
 
@@ -111,10 +111,10 @@ def test_should_follow_datalayer_style_when_changing_datalayer(
111
111
  },
112
112
  )
113
113
  page.goto(f"{live_server.url}{openmap.get_absolute_url()}?edit")
114
- marker = page.locator(".leaflet-marker-icon .icon_container")
114
+ marker = page.locator(".leaflet-marker-icon .icon-container")
115
115
  expect(marker).to_have_css("background-color", "rgb(0, 139, 139)")
116
116
  # Change datalayer
117
- marker.click()
117
+ marker.click(button="right")
118
118
  page.get_by_role("button", name="Toggle edit mode (⇧+Click)").click()
119
119
  page.locator(".umap-field-datalayer select").select_option(label="other datalayer")
120
120
  expect(marker).to_have_css("background-color", "rgb(148, 0, 211)")
@@ -87,7 +87,7 @@ def test_marker_style_should_have_precedence(live_server, openmap, page, bootstr
87
87
 
88
88
  def test_should_open_an_edit_toolbar_on_click(live_server, openmap, page, bootstrap):
89
89
  page.goto(f"{live_server.url}{openmap.get_absolute_url()}?edit")
90
- page.locator("path").click()
90
+ page.locator("path").click(button="right")
91
91
  expect(page.get_by_role("button", name="Toggle edit mode")).to_be_visible()
92
92
  expect(page.get_by_role("button", name="Delete this feature")).to_be_visible()
93
93
 
@@ -97,7 +97,7 @@ def test_can_remove_stroke(live_server, openmap, page, bootstrap):
97
97
  expect(page.locator(".leaflet-overlay-pane path[stroke='DarkBlue']")).to_have_count(
98
98
  1
99
99
  )
100
- page.locator("path").click()
100
+ page.locator("path").click(button="right")
101
101
  page.get_by_role("button", name="Toggle edit mode").click()
102
102
  page.get_by_text("Shape properties").click()
103
103
  page.locator(".umap-field-stroke .define").first.click()