Hunted the last of the \t's to extinction
This commit is contained in:
@@ -12,46 +12,46 @@
|
||||
|
||||
<script lang="js">
|
||||
export default {
|
||||
props: {
|
||||
wideColumns: Boolean,
|
||||
},
|
||||
props: {
|
||||
wideColumns: Boolean,
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="css">
|
||||
.column-layout {
|
||||
column-count: 12;
|
||||
column-fill: balance;
|
||||
column-gap: 0;
|
||||
column-width: 240px;
|
||||
transform: translateZ(0);
|
||||
padding: 4px;
|
||||
column-count: 12;
|
||||
column-fill: balance;
|
||||
column-gap: 0;
|
||||
column-width: 240px;
|
||||
transform: translateZ(0);
|
||||
padding: 4px;
|
||||
}
|
||||
|
||||
.column-layout.wide-columns {
|
||||
column-count: 12;
|
||||
column-fill: balance;
|
||||
column-gap: 0;
|
||||
column-width: 320px;
|
||||
transform: translateZ(0);
|
||||
padding: 4px;
|
||||
column-count: 12;
|
||||
column-fill: balance;
|
||||
column-gap: 0;
|
||||
column-width: 320px;
|
||||
transform: translateZ(0);
|
||||
padding: 4px;
|
||||
}
|
||||
|
||||
.column-layout>div,
|
||||
.column-layout>span>div {
|
||||
/*
|
||||
/*
|
||||
Table and width set because firefox does not support break-inside: avoid
|
||||
*/
|
||||
display: table;
|
||||
table-layout: fixed;
|
||||
width: 100%;
|
||||
backface-visibility: hidden;
|
||||
-webkit-backface-visibility: hidden;
|
||||
transform: translateX(0);
|
||||
-webkit-transform: translateX(0);
|
||||
-webkit-column-break-inside: avoid;
|
||||
page-break-inside: avoid;
|
||||
break-inside: avoid;
|
||||
padding: 4px;
|
||||
display: table;
|
||||
table-layout: fixed;
|
||||
width: 100%;
|
||||
backface-visibility: hidden;
|
||||
-webkit-backface-visibility: hidden;
|
||||
transform: translateX(0);
|
||||
-webkit-transform: translateX(0);
|
||||
-webkit-column-break-inside: avoid;
|
||||
page-break-inside: avoid;
|
||||
break-inside: avoid;
|
||||
padding: 4px;
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -19,72 +19,72 @@ import TreeNodeList from '/imports/ui/components/tree/TreeNodeList.vue';
|
||||
import { organizeDoc, reorderDoc } from '/imports/api/parenting/organizeMethods.js';
|
||||
|
||||
export default {
|
||||
components: {
|
||||
TreeNodeList,
|
||||
},
|
||||
props: {
|
||||
root: {
|
||||
type: Object,
|
||||
default: undefined,
|
||||
},
|
||||
organize: Boolean,
|
||||
selectedNode: {
|
||||
type: Object,
|
||||
default: undefined,
|
||||
},
|
||||
filter: {
|
||||
type: Object,
|
||||
default: undefined,
|
||||
},
|
||||
group: {
|
||||
type: String,
|
||||
default: 'creatureProperties'
|
||||
},
|
||||
expanded: Boolean,
|
||||
},
|
||||
meteor: {
|
||||
children() {
|
||||
const children = nodesToTree({
|
||||
collection: CreatureProperties,
|
||||
ancestorId: this.root.id,
|
||||
filter: this.filter,
|
||||
includeFilteredDocAncestors: true,
|
||||
includeFilteredDocDescendants: true,
|
||||
});
|
||||
this.$emit('length', children.length);
|
||||
return children;
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
reordered({ doc, newIndex }) {
|
||||
reorderDoc.call({
|
||||
docRef: {
|
||||
id: doc._id,
|
||||
collection: 'creatureProperties',
|
||||
},
|
||||
order: newIndex,
|
||||
});
|
||||
},
|
||||
reorganized({ doc, parent, newIndex }) {
|
||||
let parentRef;
|
||||
if (parent) {
|
||||
parentRef = {
|
||||
id: parent._id,
|
||||
collection: 'creatureProperties',
|
||||
};
|
||||
} else {
|
||||
parentRef = this.root;
|
||||
}
|
||||
organizeDoc.call({
|
||||
docRef: {
|
||||
id: doc._id,
|
||||
collection: 'creatureProperties',
|
||||
},
|
||||
parentRef,
|
||||
order: newIndex,
|
||||
});
|
||||
},
|
||||
},
|
||||
components: {
|
||||
TreeNodeList,
|
||||
},
|
||||
props: {
|
||||
root: {
|
||||
type: Object,
|
||||
default: undefined,
|
||||
},
|
||||
organize: Boolean,
|
||||
selectedNode: {
|
||||
type: Object,
|
||||
default: undefined,
|
||||
},
|
||||
filter: {
|
||||
type: Object,
|
||||
default: undefined,
|
||||
},
|
||||
group: {
|
||||
type: String,
|
||||
default: 'creatureProperties'
|
||||
},
|
||||
expanded: Boolean,
|
||||
},
|
||||
meteor: {
|
||||
children() {
|
||||
const children = nodesToTree({
|
||||
collection: CreatureProperties,
|
||||
ancestorId: this.root.id,
|
||||
filter: this.filter,
|
||||
includeFilteredDocAncestors: true,
|
||||
includeFilteredDocDescendants: true,
|
||||
});
|
||||
this.$emit('length', children.length);
|
||||
return children;
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
reordered({ doc, newIndex }) {
|
||||
reorderDoc.call({
|
||||
docRef: {
|
||||
id: doc._id,
|
||||
collection: 'creatureProperties',
|
||||
},
|
||||
order: newIndex,
|
||||
});
|
||||
},
|
||||
reorganized({ doc, parent, newIndex }) {
|
||||
let parentRef;
|
||||
if (parent) {
|
||||
parentRef = {
|
||||
id: parent._id,
|
||||
collection: 'creatureProperties',
|
||||
};
|
||||
} else {
|
||||
parentRef = this.root;
|
||||
}
|
||||
organizeDoc.call({
|
||||
docRef: {
|
||||
id: doc._id,
|
||||
collection: 'creatureProperties',
|
||||
},
|
||||
parentRef,
|
||||
order: newIndex,
|
||||
});
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
|
||||
@@ -2,65 +2,65 @@ import { parse, stringify } from 'css-box-shadow';
|
||||
|
||||
// Only supports border radius defined like "20px" or "100%"
|
||||
const transformedRadius = (radiusString, deltaWidth, deltaHeight) => {
|
||||
if (/^\d+\.?\d*px$/.test(radiusString)) {
|
||||
//The radius is defined in pixel units, so get the radius as a number
|
||||
const rad = +radiusString.match(/\d+\.?\d*/)[0];
|
||||
// Set the x and y radius of the "to" element, compensating for scale
|
||||
return `${rad / deltaWidth}px / ${rad / deltaHeight}px`;
|
||||
} else if (/^\d+\.?\d*%$/.test(radiusString)) {
|
||||
//The radius is defined as a percentage, so just use it as is
|
||||
return radiusString;
|
||||
}
|
||||
if (/^\d+\.?\d*px$/.test(radiusString)) {
|
||||
//The radius is defined in pixel units, so get the radius as a number
|
||||
const rad = +radiusString.match(/\d+\.?\d*/)[0];
|
||||
// Set the x and y radius of the "to" element, compensating for scale
|
||||
return `${rad / deltaWidth}px / ${rad / deltaHeight}px`;
|
||||
} else if (/^\d+\.?\d*%$/.test(radiusString)) {
|
||||
//The radius is defined as a percentage, so just use it as is
|
||||
return radiusString;
|
||||
}
|
||||
};
|
||||
|
||||
const transformedBoxShadow = (shadowString, deltaWidth, deltaHeight) => {
|
||||
if (shadowString === 'none') return shadowString;
|
||||
if (shadowString[0] === 'r') {
|
||||
let strings = shadowString.match(/rgba\([^)]+\)[^,]+/g);
|
||||
strings = strings.map(string => {
|
||||
// Move color to end
|
||||
let m = string.match(/(rgba\([^)]+\))([^,]+)/);
|
||||
return `${m[2].trim()} ${m[1]}`;
|
||||
});
|
||||
shadowString = strings.join(', ');
|
||||
}
|
||||
let scaleAverage = (deltaWidth + deltaHeight) / 2;
|
||||
let shadows = parse(shadowString);
|
||||
shadows.forEach(shadow => {
|
||||
shadow.offsetX /= deltaWidth;
|
||||
shadow.offsetY /= deltaHeight;
|
||||
shadow.blurRadius /= scaleAverage;
|
||||
shadow.spreadRadius /= scaleAverage;
|
||||
})
|
||||
return stringify(shadows);
|
||||
if (shadowString === 'none') return shadowString;
|
||||
if (shadowString[0] === 'r') {
|
||||
let strings = shadowString.match(/rgba\([^)]+\)[^,]+/g);
|
||||
strings = strings.map(string => {
|
||||
// Move color to end
|
||||
let m = string.match(/(rgba\([^)]+\))([^,]+)/);
|
||||
return `${m[2].trim()} ${m[1]}`;
|
||||
});
|
||||
shadowString = strings.join(', ');
|
||||
}
|
||||
let scaleAverage = (deltaWidth + deltaHeight) / 2;
|
||||
let shadows = parse(shadowString);
|
||||
shadows.forEach(shadow => {
|
||||
shadow.offsetX /= deltaWidth;
|
||||
shadow.offsetY /= deltaHeight;
|
||||
shadow.blurRadius /= scaleAverage;
|
||||
shadow.spreadRadius /= scaleAverage;
|
||||
})
|
||||
return stringify(shadows);
|
||||
}
|
||||
|
||||
export default function mockElement({ source, target, offset = { x: 0, y: 0 } }) {
|
||||
if (!source || !target) throw `Can't mock without ${source ? 'target' : 'source'}`;
|
||||
let sourceRect = source.getBoundingClientRect();
|
||||
let targetRect = target.getBoundingClientRect();
|
||||
if (!source || !target) throw `Can't mock without ${source ? 'target' : 'source'}`;
|
||||
let sourceRect = source.getBoundingClientRect();
|
||||
let targetRect = target.getBoundingClientRect();
|
||||
|
||||
// Get how must the target change to become the source
|
||||
const deltaWidth = sourceRect.width / targetRect.width;
|
||||
const deltaHeight = sourceRect.height / targetRect.height;
|
||||
const deltaLeft = sourceRect.left - targetRect.left + offset.x;
|
||||
const deltaTop = sourceRect.top - targetRect.top + offset.y;
|
||||
// Mock the source
|
||||
target.style.transform = `translate(${deltaLeft}px, ${deltaTop}px) ` +
|
||||
`scale(${deltaWidth}, ${deltaHeight})`;
|
||||
// Mock the background color unless it's completely transparent
|
||||
let backgroundColor = getComputedStyle(source).backgroundColor
|
||||
if (backgroundColor !== 'rgba(0, 0, 0, 0)') {
|
||||
target.style.backgroundColor = backgroundColor;
|
||||
}
|
||||
// Edge might not combine all border radii into a single value,
|
||||
// So we just sample the top left one if we need to
|
||||
let oldRadius = getComputedStyle(source).borderRadius ||
|
||||
getComputedStyle(source).borderTopLeftRadius;
|
||||
let borderRadius = transformedRadius(oldRadius, deltaWidth, deltaHeight);
|
||||
target.style.borderRadius = borderRadius;
|
||||
let boxShadow = transformedBoxShadow(
|
||||
getComputedStyle(source).boxShadow, deltaWidth, deltaHeight
|
||||
);
|
||||
target.style.setProperty('box-shadow', boxShadow, 'important');
|
||||
// Get how must the target change to become the source
|
||||
const deltaWidth = sourceRect.width / targetRect.width;
|
||||
const deltaHeight = sourceRect.height / targetRect.height;
|
||||
const deltaLeft = sourceRect.left - targetRect.left + offset.x;
|
||||
const deltaTop = sourceRect.top - targetRect.top + offset.y;
|
||||
// Mock the source
|
||||
target.style.transform = `translate(${deltaLeft}px, ${deltaTop}px) ` +
|
||||
`scale(${deltaWidth}, ${deltaHeight})`;
|
||||
// Mock the background color unless it's completely transparent
|
||||
let backgroundColor = getComputedStyle(source).backgroundColor
|
||||
if (backgroundColor !== 'rgba(0, 0, 0, 0)') {
|
||||
target.style.backgroundColor = backgroundColor;
|
||||
}
|
||||
// Edge might not combine all border radii into a single value,
|
||||
// So we just sample the top left one if we need to
|
||||
let oldRadius = getComputedStyle(source).borderRadius ||
|
||||
getComputedStyle(source).borderTopLeftRadius;
|
||||
let borderRadius = transformedRadius(oldRadius, deltaWidth, deltaHeight);
|
||||
target.style.borderRadius = borderRadius;
|
||||
let boxShadow = transformedBoxShadow(
|
||||
getComputedStyle(source).boxShadow, deltaWidth, deltaHeight
|
||||
);
|
||||
target.style.setProperty('box-shadow', boxShadow, 'important');
|
||||
}
|
||||
|
||||
@@ -25,41 +25,41 @@ import propertyViewerMixin from '/imports/ui/properties/viewers/shared/propertyV
|
||||
import numberToSignedString from '/imports/ui/utility/numberToSignedString.js';
|
||||
|
||||
export default {
|
||||
mixins: [propertyViewerMixin],
|
||||
computed: {
|
||||
reset() {
|
||||
let reset = this.model.reset
|
||||
if (reset === 'shortRest') {
|
||||
return `Reset${this.model.resetMultiplier && ' x' + this.model.resetMultiplier
|
||||
} on a short rest`;
|
||||
} else if (reset === 'longRest') {
|
||||
return `Reset${this.model.resetMultiplier && ' x' + this.model.resetMultiplier
|
||||
} on a long rest`;
|
||||
} else {
|
||||
return undefined;
|
||||
}
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
numberToSignedString,
|
||||
}
|
||||
mixins: [propertyViewerMixin],
|
||||
computed: {
|
||||
reset() {
|
||||
let reset = this.model.reset
|
||||
if (reset === 'shortRest') {
|
||||
return `Reset${this.model.resetMultiplier && ' x' + this.model.resetMultiplier
|
||||
} on a short rest`;
|
||||
} else if (reset === 'longRest') {
|
||||
return `Reset${this.model.resetMultiplier && ' x' + this.model.resetMultiplier
|
||||
} on a long rest`;
|
||||
} else {
|
||||
return undefined;
|
||||
}
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
numberToSignedString,
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="css" scoped>
|
||||
.ability-value {
|
||||
font-weight: 600;
|
||||
font-size: 24px !important;
|
||||
color: rgba(0, 0, 0, 0.54);
|
||||
font-weight: 600;
|
||||
font-size: 24px !important;
|
||||
color: rgba(0, 0, 0, 0.54);
|
||||
}
|
||||
|
||||
.mod,
|
||||
.ability-value {
|
||||
text-align: center;
|
||||
width: 100%;
|
||||
text-align: center;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.attribute-value {
|
||||
text-align: center;
|
||||
text-align: center;
|
||||
}
|
||||
</style>
|
||||
|
||||
Reference in New Issue
Block a user