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.
- umap/__init__.py +1 -1
- umap/locale/el/LC_MESSAGES/django.mo +0 -0
- umap/locale/el/LC_MESSAGES/django.po +42 -38
- umap/locale/en/LC_MESSAGES/django.mo +0 -0
- umap/locale/en/LC_MESSAGES/django.po +15 -15
- umap/locale/hu/LC_MESSAGES/django.mo +0 -0
- umap/locale/hu/LC_MESSAGES/django.po +39 -35
- umap/locale/nl/LC_MESSAGES/django.mo +0 -0
- umap/locale/nl/LC_MESSAGES/django.po +31 -27
- umap/settings/base.py +2 -0
- umap/static/umap/css/contextmenu.css +58 -2
- umap/static/umap/css/form.css +175 -45
- umap/static/umap/css/icon.css +20 -0
- umap/static/umap/img/16-white.svg +21 -40
- umap/static/umap/img/16.svg +1 -1
- umap/static/umap/img/24-white.svg +9 -9
- umap/static/umap/img/24.svg +23 -10
- umap/static/umap/img/source/16-white.svg +23 -41
- umap/static/umap/img/source/16.svg +1 -1
- umap/static/umap/img/source/24-white.svg +11 -11
- umap/static/umap/img/source/24.svg +25 -12
- umap/static/umap/js/modules/caption.js +8 -0
- umap/static/umap/js/modules/data/features.js +318 -174
- umap/static/umap/js/modules/data/layer.js +27 -20
- umap/static/umap/js/modules/form/builder.js +11 -7
- umap/static/umap/js/modules/form/fields.js +10 -7
- umap/static/umap/js/modules/formatter.js +42 -20
- umap/static/umap/js/modules/importer.js +6 -1
- umap/static/umap/js/modules/importers/opendata.js +125 -37
- umap/static/umap/js/modules/importers/openrouteservice.js +140 -0
- umap/static/umap/js/modules/managers.js +12 -4
- umap/static/umap/js/modules/printer.js +107 -0
- umap/static/umap/js/modules/rendering/controls.js +78 -2
- umap/static/umap/js/modules/rendering/icon.js +113 -82
- umap/static/umap/js/modules/rendering/layers/cluster.js +220 -64
- umap/static/umap/js/modules/rendering/map.js +5 -1
- umap/static/umap/js/modules/rendering/template.js +71 -1
- umap/static/umap/js/modules/rendering/ui.js +101 -34
- umap/static/umap/js/modules/schema.js +24 -0
- umap/static/umap/js/modules/share.js +19 -12
- umap/static/umap/js/modules/ui/bar.js +6 -1
- umap/static/umap/js/modules/ui/base.js +24 -9
- umap/static/umap/js/modules/ui/contextmenu.js +17 -7
- umap/static/umap/js/modules/ui/dialog.js +7 -4
- umap/static/umap/js/modules/umap.js +68 -62
- umap/static/umap/js/umap.controls.js +22 -57
- umap/static/umap/locale/am_ET.js +39 -4
- umap/static/umap/locale/am_ET.json +39 -4
- umap/static/umap/locale/ar.js +39 -4
- umap/static/umap/locale/ar.json +39 -4
- umap/static/umap/locale/ast.js +39 -4
- umap/static/umap/locale/ast.json +39 -4
- umap/static/umap/locale/bg.js +39 -4
- umap/static/umap/locale/bg.json +39 -4
- umap/static/umap/locale/br.js +39 -4
- umap/static/umap/locale/br.json +39 -4
- umap/static/umap/locale/ca.js +39 -4
- umap/static/umap/locale/ca.json +39 -4
- umap/static/umap/locale/cs_CZ.js +39 -4
- umap/static/umap/locale/cs_CZ.json +39 -4
- umap/static/umap/locale/da.js +47 -12
- umap/static/umap/locale/da.json +47 -12
- umap/static/umap/locale/de.js +39 -4
- umap/static/umap/locale/de.json +39 -4
- umap/static/umap/locale/el.js +81 -46
- umap/static/umap/locale/el.json +81 -46
- umap/static/umap/locale/en.js +38 -4
- umap/static/umap/locale/en.json +38 -4
- umap/static/umap/locale/en_US.json +39 -4
- umap/static/umap/locale/es.js +47 -12
- umap/static/umap/locale/es.json +47 -12
- umap/static/umap/locale/et.js +39 -4
- umap/static/umap/locale/et.json +39 -4
- umap/static/umap/locale/eu.js +80 -45
- umap/static/umap/locale/eu.json +80 -45
- umap/static/umap/locale/fa_IR.js +39 -4
- umap/static/umap/locale/fa_IR.json +39 -4
- umap/static/umap/locale/fi.js +39 -4
- umap/static/umap/locale/fi.json +39 -4
- umap/static/umap/locale/fr.js +39 -4
- umap/static/umap/locale/fr.json +39 -4
- umap/static/umap/locale/gl.js +39 -4
- umap/static/umap/locale/gl.json +39 -4
- umap/static/umap/locale/he.js +39 -4
- umap/static/umap/locale/he.json +39 -4
- umap/static/umap/locale/hr.js +39 -4
- umap/static/umap/locale/hr.json +39 -4
- umap/static/umap/locale/hu.js +55 -20
- umap/static/umap/locale/hu.json +55 -20
- umap/static/umap/locale/id.js +39 -4
- umap/static/umap/locale/id.json +39 -4
- umap/static/umap/locale/is.js +39 -4
- umap/static/umap/locale/is.json +39 -4
- umap/static/umap/locale/it.js +39 -4
- umap/static/umap/locale/it.json +39 -4
- umap/static/umap/locale/ja.js +39 -4
- umap/static/umap/locale/ja.json +39 -4
- umap/static/umap/locale/ko.js +39 -4
- umap/static/umap/locale/ko.json +39 -4
- umap/static/umap/locale/lt.js +39 -4
- umap/static/umap/locale/lt.json +39 -4
- umap/static/umap/locale/ms.js +52 -17
- umap/static/umap/locale/ms.json +52 -17
- umap/static/umap/locale/nl.js +58 -23
- umap/static/umap/locale/nl.json +58 -23
- umap/static/umap/locale/no.js +39 -4
- umap/static/umap/locale/no.json +39 -4
- umap/static/umap/locale/pl.js +39 -4
- umap/static/umap/locale/pl.json +39 -4
- umap/static/umap/locale/pl_PL.json +39 -4
- umap/static/umap/locale/pt.js +39 -4
- umap/static/umap/locale/pt.json +39 -4
- umap/static/umap/locale/pt_BR.js +39 -4
- umap/static/umap/locale/pt_BR.json +39 -4
- umap/static/umap/locale/pt_PT.js +39 -4
- umap/static/umap/locale/pt_PT.json +39 -4
- umap/static/umap/locale/ro.js +39 -4
- umap/static/umap/locale/ro.json +39 -4
- umap/static/umap/locale/ru.js +39 -4
- umap/static/umap/locale/ru.json +39 -4
- umap/static/umap/locale/sk_SK.js +39 -4
- umap/static/umap/locale/sk_SK.json +39 -4
- umap/static/umap/locale/sl.js +39 -4
- umap/static/umap/locale/sl.json +39 -4
- umap/static/umap/locale/sr.js +39 -4
- umap/static/umap/locale/sr.json +39 -4
- umap/static/umap/locale/sv.js +39 -4
- umap/static/umap/locale/sv.json +39 -4
- umap/static/umap/locale/th_TH.js +39 -4
- umap/static/umap/locale/th_TH.json +39 -4
- umap/static/umap/locale/tr.js +39 -4
- umap/static/umap/locale/tr.json +39 -4
- umap/static/umap/locale/uk_UA.js +39 -4
- umap/static/umap/locale/uk_UA.json +39 -4
- umap/static/umap/locale/vi.js +39 -4
- umap/static/umap/locale/vi.json +39 -4
- umap/static/umap/locale/vi_VN.json +39 -4
- umap/static/umap/locale/zh.js +39 -4
- umap/static/umap/locale/zh.json +39 -4
- umap/static/umap/locale/zh_CN.json +39 -4
- umap/static/umap/locale/zh_TW.Big5.json +39 -4
- umap/static/umap/locale/zh_TW.js +98 -63
- umap/static/umap/locale/zh_TW.json +98 -63
- umap/static/umap/map.css +90 -41
- umap/static/umap/vars.css +1 -0
- umap/static/umap/vendors/editable/Leaflet.Editable.js +3 -1
- umap/static/umap/vendors/openrouteservice/ors-js-client.js +521 -0
- umap/static/umap/vendors/openrouteservice/ors-js-client.js.map +1 -0
- umap/static/umap/vendors/simple-elevation-chart/elevation.js +63 -0
- umap/static/umap/vendors/simple-elevation-chart/elevation.svg +8 -0
- umap/static/umap/vendors/snapdom/snapdom.min.mjs +3 -0
- umap/storage/staticfiles.py +12 -0
- umap/templates/umap/css.html +0 -4
- umap/templates/umap/js.html +1 -3
- umap/tests/integration/test_basics.py +2 -0
- umap/tests/integration/test_conditional_rules.py +17 -17
- umap/tests/integration/test_datalayer.py +1 -1
- umap/tests/integration/test_draw_polygon.py +3 -5
- umap/tests/integration/test_draw_polyline.py +4 -6
- umap/tests/integration/test_draw_route.py +178 -0
- umap/tests/integration/test_edit_map.py +1 -1
- umap/tests/integration/test_edit_marker.py +7 -7
- umap/tests/integration/test_edit_polygon.py +2 -2
- umap/tests/integration/test_export_map.py +74 -10
- umap/tests/integration/test_map_preview.py +1 -1
- umap/tests/integration/test_share.py +1 -1
- umap/tests/integration/test_tableeditor.py +4 -4
- umap/tests/integration/test_websocket_sync.py +4 -4
- umap/utils.py +5 -1
- umap/views.py +2 -0
- {umap_project-3.2.0.dist-info → umap_project-3.3.1.dist-info}/METADATA +9 -9
- {umap_project-3.2.0.dist-info → umap_project-3.3.1.dist-info}/RECORD +175 -171
- umap/static/umap/vendors/markercluster/MarkerCluster.Default.css +0 -60
- umap/static/umap/vendors/markercluster/MarkerCluster.css +0 -14
- umap/static/umap/vendors/markercluster/leaflet.markercluster.js +0 -2
- umap/static/umap/vendors/markercluster/leaflet.markercluster.js.map +0 -1
- {umap_project-3.2.0.dist-info → umap_project-3.3.1.dist-info}/WHEEL +0 -0
- {umap_project-3.2.0.dist-info → umap_project-3.3.1.dist-info}/entry_points.txt +0 -0
- {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};
|
umap/storage/staticfiles.py
CHANGED
|
@@ -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:
|
umap/templates/umap/css.html
CHANGED
|
@@ -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"
|
umap/templates/umap/js.html
CHANGED
|
@@ -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>
|
|
@@ -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 .
|
|
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 .
|
|
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 .
|
|
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 .
|
|
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 .
|
|
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 .
|
|
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 .
|
|
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 .
|
|
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 .
|
|
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 .
|
|
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 .
|
|
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 .
|
|
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 .
|
|
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 .
|
|
335
|
-
drops = page.locator(".umap-drop-icon .
|
|
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 .
|
|
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 .
|
|
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 .
|
|
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":
|
|
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 .
|
|
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 .
|
|
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 .
|
|
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 .
|
|
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 .
|
|
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 .
|
|
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()
|