Lots of changes to the cmap stuff

This commit is contained in:
2026-08-22 13:51:15 +02:00
parent 63b7ca0853
commit 20c1584016
17 changed files with 3105 additions and 204 deletions
File diff suppressed because it is too large Load Diff
+377 -25
View File
@@ -13,6 +13,7 @@ body.cmap-mode #main {
height: 100vh;
min-height: 0;
overflow: auto;
padding-top: 0;
}
#cmap-view {
@@ -24,7 +25,7 @@ body.cmap-mode #main {
z-index: 160;
top: 0;
margin: 0 0 10px;
padding: 6px 0;
padding: 34px 0 6px;
background: rgb(255 255 255 / 96%);
box-shadow: 0 1px 0 rgb(128 139 150 / 22%);
backdrop-filter: blur(4px);
@@ -51,6 +52,45 @@ body.cmap-mode #main {
min-width: 16px;
}
.cmap-hidden-items {
position: relative;
flex: 0 0 auto;
}
.cmap-hidden-items > summary {
cursor: pointer;
white-space: nowrap;
}
.cmap-hidden-item-options {
position: absolute;
top: calc(100% + 6px);
left: 0;
z-index: 10020;
display: grid;
min-width: 220px;
max-height: 320px;
overflow: auto;
padding: 6px;
border: 1px solid #c8ced5;
border-radius: 5px;
background: #fff;
box-shadow: 0 8px 24px rgb(0 0 0 / 18%);
}
.cmap-hidden-item-options button {
padding: 7px 9px;
border: 0;
background: transparent;
text-align: left;
cursor: pointer;
}
.cmap-hidden-item-options button:hover,
.cmap-hidden-item-options button:focus-visible {
background: #eef2f6;
}
.cmap-storage-controls input[type="search"] {
box-sizing: border-box;
min-width: 220px;
@@ -60,6 +100,20 @@ body.cmap-mode #main {
font: inherit;
}
.cmap-wiki-reference {
max-width: 300px;
overflow: hidden;
padding: 5px 8px;
border: 1px solid #c3cad2;
border-radius: 4px;
background: #f7f9fa;
color: #34495e;
cursor: copy;
font: 12px/1.4 ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
text-overflow: ellipsis;
white-space: nowrap;
}
.wiki-combobox {
position: relative;
min-width: 220px;
@@ -225,6 +279,8 @@ body.cmap-mode #main {
.cmap-workspace {
position: relative;
z-index: 0;
isolation: isolate;
width: 100%;
}
@@ -337,7 +393,7 @@ body.cmap-mode #main {
.cmap-context-menu {
position: fixed;
z-index: 500;
z-index: 100000;
display: grid;
min-width: 210px;
padding: 5px;
@@ -406,23 +462,131 @@ body.cmap-mode #main {
}
.cmap-card {
position: relative;
height: 100%;
box-sizing: border-box;
padding: 9px 11px;
overflow: hidden;
}
.rw-cmap-view-description {
position: absolute;
top: 3px;
left: 3px;
z-index: 46;
display: grid;
width: 20px;
height: 20px;
padding: 0;
place-items: center;
border: 1px solid rgb(70 82 94 / 45%);
border-radius: 50%;
background: #fff;
color: #34495e;
cursor: pointer;
font: 700 14px/1 Georgia, "Times New Roman", serif;
}
.rw-cmap-view-description.is-empty {
border-color: #c8cdd2;
background: #e5e7e9;
color: #7a828a;
}
.rw-cmap-view-description.is-filled {
border-color: #87919b;
background: #fff;
color: #263746;
}
.cmap-description-tooltip {
position: fixed;
z-index: 110000;
width: min(420px, calc(100vw - 16px));
max-height: min(440px, calc(100vh - 24px));
overflow: auto;
padding: 12px 14px;
border: 1px solid #9ca6b0;
border-radius: 7px;
background: #fff;
box-shadow: 0 10px 32px rgb(0 0 0 / 24%);
color: #222;
font: 14px/1.45 system-ui, sans-serif;
pointer-events: none;
}
.cmap-description-tooltip .markdown-body > :first-child { margin-top: 0; }
.cmap-description-tooltip .markdown-body > :last-child { margin-bottom: 0; }
.rw-cmap-open-linked {
position: absolute;
z-index: 46;
top: 3px;
right: 3px;
display: grid;
width: 20px;
height: 20px;
padding: 0;
place-items: center;
border: 1px solid rgb(70 82 94 / 45%);
border-radius: 50%;
background: rgb(255 255 255 / 86%);
color: #34495e;
cursor: pointer;
font: 700 12px/1 Arial, Helvetica, sans-serif;
}
.rw-cmap-view-description + .cmap-card-image,
.rw-cmap-view-description ~ .cmap-card-title {
padding-left: 16px;
}
.rw-cmap-open-linked ~ .cmap-card-title {
padding-right: 16px;
}
.cmap-card-title {
margin-bottom: .3rem;
font-size: 1rem;
font-weight: 700;
font-size: 1em;
font-weight: inherit;
font-style: inherit;
}
.cmap-card-usage {
opacity: .62;
font-size: .72em;
font-style: normal;
font-weight: 400;
white-space: nowrap;
}
.cmap-card-aspects {
display: flex;
flex-wrap: wrap;
gap: 3px;
margin: 0 0 .35rem;
}
.cmap-card-aspect {
padding: 1px 5px;
border: 1px solid color-mix(in srgb, currentColor 35%, transparent);
border-radius: 999px;
background: rgb(255 255 255 / 58%);
font-size: .68em;
font-weight: 600;
line-height: 1.35;
}
.cmap-card-synopsis {
color: inherit;
opacity: .78;
font-size: .84rem;
font-size: .84em;
line-height: 1.25;
font-weight: inherit;
font-style: inherit;
overflow-wrap: anywhere;
white-space: normal;
word-break: break-word;
}
.cmap-card-image {
@@ -434,18 +598,6 @@ body.cmap-mode #main {
object-fit: contain;
}
.cmap-card-page .cmap-card-title::after {
content: " ↗";
color: #4479a1;
font-weight: 400;
}
.cmap-card-linked-cmap .cmap-card-title::after {
content: " ↗";
color: #477b3e;
font-weight: 400;
}
.rw-cmap-item {
overflow: visible !important;
}
@@ -466,10 +618,30 @@ body.cmap-mode #main {
font: 700 17px/18px Arial, Helvetica, sans-serif;
}
.rw-cmap-submap-open {
position: absolute;
top: 6px;
right: 34px;
z-index: 45;
width: 22px;
height: 22px;
padding: 0;
border: 1px solid #57834a;
border-radius: 50%;
background: #fff;
color: #35672c;
cursor: pointer;
font: 700 14px/18px Arial, Helvetica, sans-serif;
}
.cmap-card-submap {
padding-right: 38px;
}
.rw-cmap-item:has(> .rw-cmap-submap-open) .cmap-card-submap {
padding-right: 64px;
}
.rw-cmap-submap-frame {
position: absolute;
z-index: 0;
@@ -487,6 +659,23 @@ body.cmap-mode #main {
user-select: none;
}
.rw-cmap-submap-anchor-line {
position: absolute;
inset: 0;
z-index: 1;
width: 100%;
height: 100%;
overflow: visible;
pointer-events: none;
}
.rw-cmap-submap-anchor-line path {
fill: none;
stroke: #a6adb4;
stroke-width: 2;
stroke-linecap: round;
}
.rw-cmap-submap-frame-selected {
outline: 3px solid #9994ff;
outline-offset: 2px;
@@ -510,6 +699,43 @@ body.cmap-mode #main {
pointer-events: auto;
}
.rw-cmap-boundary-layer,
.rw-cmap-boundary-lines {
position: absolute;
inset: 0;
z-index: 16;
width: 100%;
height: 100%;
overflow: visible;
pointer-events: none;
}
.rw-cmap-boundary-reference {
position: absolute;
z-index: 17;
min-height: 30px;
overflow: hidden;
padding: 5px 9px;
border: 1px solid #77838e;
border-radius: 5px;
background: #fff;
color: #25313c;
text-align: left;
text-overflow: ellipsis;
white-space: nowrap;
cursor: pointer;
pointer-events: auto;
box-shadow: 0 2px 6px rgb(0 0 0 / 14%);
}
.rw-cmap-boundary-reference-left::before {
content: "← ";
}
.rw-cmap-boundary-reference-right::after {
content: " →";
}
.rw-cmap-selected {
z-index: 20 !important;
outline: 3px solid #9994ff !important;
@@ -660,6 +886,11 @@ body.cmap-mode #main {
box-shadow: 0 18px 60px rgb(0 0 0 / 24%);
}
#cmap-concept-dialog {
width: min(780px, calc(100vw - 32px));
max-height: calc(100vh - 32px);
}
.cmap-concept-dialog::backdrop {
background: rgb(22 30 44 / 38%);
}
@@ -695,6 +926,8 @@ body.cmap-mode #main {
#cmap-history-list { max-height: min(520px, 60vh); overflow: auto; }
.cmap-history-row { display: grid; grid-template-columns: minmax(0, 1fr) auto; gap: 12px; align-items: center; padding: 11px 0; border-bottom: 1px solid #dfe3e8; }
.cmap-history-row:last-child { border-bottom: 0; }
.cmap-history-actions { display: flex; gap: 8px; align-items: center; }
.cmap-history-empty { margin: 18px 0 4px; }
.cmap-unsaved-dialog form {
display: grid;
@@ -713,6 +946,21 @@ body.cmap-mode #main {
padding: 22px;
}
#cmap-concept-form {
grid-template-columns: repeat(2, minmax(0, 1fr));
gap: 11px 14px;
max-height: calc(100vh - 34px);
overflow: auto;
padding: 18px;
}
#cmap-concept-form > h2,
#cmap-concept-form > .cmap-dialog-wide,
#cmap-concept-form > .cmap-submap-style-fields,
#cmap-concept-form > .cmap-concept-dialog-actions {
grid-column: 1 / -1;
}
.cmap-concept-dialog h2 {
margin: 0 0 2px;
}
@@ -737,18 +985,72 @@ body.cmap-mode #main {
font-weight: 400;
}
.cmap-concept-dialog input[type="color"] {
width: 72px;
height: 36px;
padding: 2px;
border: 1px solid #aab2bd;
.cmap-color-control {
position: relative;
display: flex;
align-items: center;
gap: 6px;
font-weight: 400;
}
.cmap-concept-dialog .cmap-color-input {
width: 96px;
min-width: 0;
font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
}
.cmap-color-swatch {
width: 34px;
height: 34px;
padding: 0;
border: 1px solid #8f99a4;
border-radius: 4px;
background: #fff;
cursor: pointer;
}
.cmap-color-palette {
position: absolute;
z-index: 20;
top: calc(100% + 4px);
left: 0;
display: grid;
grid-template-columns: repeat(6, 28px);
gap: 5px;
padding: 7px;
border: 1px solid #929ca6;
border-radius: 6px;
background: #fff;
box-shadow: 0 7px 22px rgb(0 0 0 / 20%);
}
.cmap-color-palette button {
width: 28px;
height: 28px;
padding: 0;
border: 1px solid #727b84;
border-radius: 3px;
}
.cmap-color-palette button:hover,
.cmap-color-palette button:focus-visible {
outline: 2px solid #315f91;
outline-offset: 1px;
}
.cmap-native-color-picker {
position: fixed;
left: -100px;
top: -100px;
width: 1px;
height: 1px;
opacity: 0;
pointer-events: none;
}
.cmap-concept-image-fields,
.cmap-submap-style-fields {
.cmap-submap-style-fields,
.cmap-appearance-fields,
.cmap-typography-fields {
display: grid;
gap: 9px;
margin: 0;
@@ -758,7 +1060,9 @@ body.cmap-mode #main {
}
.cmap-concept-image-fields legend,
.cmap-submap-style-fields legend {
.cmap-submap-style-fields legend,
.cmap-appearance-fields legend,
.cmap-typography-fields legend {
padding: 0 4px;
font-weight: 600;
}
@@ -767,6 +1071,40 @@ body.cmap-mode #main {
grid-template-columns: 1fr 1fr;
}
.cmap-appearance-fields {
grid-template-columns: repeat(4, minmax(0, 1fr));
}
.cmap-typography-fields {
grid-column: 1 / -1;
grid-template-columns: repeat(5, minmax(0, 1fr));
min-width: 0;
padding: 8px 10px 10px;
}
.cmap-appearance-fields legend,
.cmap-style-preset-row {
grid-column: 1 / -1;
}
.cmap-inline-control {
display: flex;
gap: 7px;
}
.cmap-inline-control select { flex: 1 1 auto; }
#cmap-concept-form .cmap-check-label {
display: flex;
flex-direction: row;
gap: 7px;
align-items: center;
align-self: end;
min-height: 36px;
}
.cmap-check-label input { margin: 0; }
.cmap-submap-style-fields legend {
grid-column: 1 / -1;
}
@@ -825,6 +1163,20 @@ body.cmap-mode #main {
margin-top: 4px;
}
@media (max-width: 720px) {
#cmap-concept-form,
.cmap-appearance-fields,
.cmap-typography-fields {
grid-template-columns: 1fr;
}
#cmap-concept-form > *,
.cmap-appearance-fields > *,
.cmap-typography-fields > * {
grid-column: 1;
}
}
@media (max-width: 1100px) {
.cmap-storage-controls {
flex-wrap: wrap;
+38 -4
View File
@@ -1,5 +1,5 @@
/**
* racket-wiki cmap component 0.2.94
* racket-wiki cmap component 0.2.95
* Based on cmap v0.1.3.
* (c) 2015 iOnStage
* Released under the MIT License.
@@ -370,6 +370,12 @@
var Component = function() {};
Component.prototype.disposed = false;
Component.prototype.dispose = function() {
this.disposed = true;
};
Component.prototype.prop = function(initialValue, defaultValue, converter) {
if (typeof converter !== 'function')
converter = helper.identity;
@@ -407,8 +413,11 @@
var updateRelations = function(index) {
for (var i = index, len = dirtyComponents.length; i < len; i++) {
var component = dirtyComponents[i];
if (component.disposed)
continue;
component.relations().forEach(function(relation) {
relation.update(component);
if (!relation.disposed)
relation.update(component);
});
}
@@ -421,7 +430,8 @@
updateRelations(0);
dirtyComponents.forEach(function(component) {
component.redraw();
if (!component.disposed)
component.redraw();
});
dirtyComponents = [];
@@ -429,7 +439,7 @@
};
return function() {
if (dom.disabled())
if (dom.disabled() || this.disposed)
return;
if (dirtyComponents.indexOf(this) === -1)
@@ -1808,6 +1818,9 @@
};
Cmap.prototype.redraw = function() {
if (this.disposed)
return;
var rootElement = this.rootElement();
if (!rootElement) {
@@ -1820,6 +1833,7 @@
this.rootElement(rootElement);
}
var previousElement = this.element();
var element = dom.el('<div>');
element.className = 'rw-cmap-surface';
dom.draggable(element, function(x, y, event) {
@@ -1844,6 +1858,8 @@
this.unfixScrollSize();
dom.css(element, this.style());
if (previousElement && previousElement.parentNode)
previousElement.parentNode.removeChild(previousElement);
dom.append(rootElement, element);
};
@@ -2190,6 +2206,24 @@
this.activationHandler = handler;
};
CmapModule.prototype.destroy = function() {
var component = this.component;
var element = component.element();
this.selectionHandler = null;
this.activationHandler = null;
component.selectionHandler = null;
component.activationHandler = null;
component.componentList().toArray().forEach(function(child) {
child.dispose();
child.parentElement(null);
});
component.dispose();
if (element && element.parentNode)
element.parentNode.removeChild(element);
};
CmapModule.prototype.zoom = function(value) {
if (typeof value === 'undefined')
return this.component.zoomFactor;