mirror of
https://github.com/niklasvh/html2canvas.git
synced 2023-08-10 21:13:10 +03:00
feat: add support for 'auto' values in clip property
This commit is contained in:
parent
83eec2d24a
commit
5d2f14f37f
@ -1,31 +1,34 @@
|
||||
import {IPropertyValueDescriptor, PropertyDescriptorParsingType} from '../IPropertyDescriptor';
|
||||
import {CSSValue, isDimensionToken, isIdentWithValue, nonFunctionArgSeparator} from '../syntax/parser';
|
||||
import {CSSValue, isAutoIdentToken, isDimensionToken} from '../syntax/parser';
|
||||
import {Context} from '../../core/context';
|
||||
import {DimensionToken, TokenType} from '../syntax/tokenizer';
|
||||
import {AutoIdentToken, DimensionToken, TokenType} from '../syntax/tokenizer';
|
||||
|
||||
export interface RectClip {
|
||||
top: DimensionToken;
|
||||
right: DimensionToken;
|
||||
bottom: DimensionToken;
|
||||
left: DimensionToken;
|
||||
top: DimensionToken | AutoIdentToken;
|
||||
right: DimensionToken | AutoIdentToken;
|
||||
bottom: DimensionToken | AutoIdentToken;
|
||||
left: DimensionToken | AutoIdentToken;
|
||||
}
|
||||
|
||||
const isDimensionOrAutoToken = (token: CSSValue): token is DimensionToken | AutoIdentToken =>
|
||||
isDimensionToken(token) || isAutoIdentToken(token);
|
||||
|
||||
export const clip: IPropertyValueDescriptor<RectClip | null> = {
|
||||
name: 'clip',
|
||||
initialValue: 'auto',
|
||||
type: PropertyDescriptorParsingType.VALUE,
|
||||
prefix: false,
|
||||
parse: (_context: Context, token: CSSValue) => {
|
||||
if (isIdentWithValue(token, 'auto')) {
|
||||
if (isAutoIdentToken(token)) {
|
||||
return null;
|
||||
}
|
||||
if (token.type !== TokenType.FUNCTION || token.name !== 'rect') {
|
||||
throw new Error('Clip value must be auto or a rect function');
|
||||
}
|
||||
|
||||
const rectArgs = token.values.filter(nonFunctionArgSeparator).filter(isDimensionToken);
|
||||
const rectArgs = token.values.filter(isDimensionOrAutoToken);
|
||||
if (rectArgs.length !== 4) {
|
||||
throw new Error('Rect clip must have 4 dimension elements');
|
||||
throw new Error('Rect clip must have 4 elements that are either a dimension or "auto"');
|
||||
}
|
||||
|
||||
return {
|
||||
|
@ -1,4 +1,5 @@
|
||||
import {
|
||||
AutoIdentToken,
|
||||
CSSToken,
|
||||
DimensionToken,
|
||||
EOF_TOKEN,
|
||||
@ -145,6 +146,7 @@ export const isDimensionToken = (token: CSSValue): token is DimensionToken => to
|
||||
export const isNumberToken = (token: CSSValue): token is NumberValueToken => token.type === TokenType.NUMBER_TOKEN;
|
||||
export const isIdentToken = (token: CSSValue): token is StringValueToken => token.type === TokenType.IDENT_TOKEN;
|
||||
export const isStringToken = (token: CSSValue): token is StringValueToken => token.type === TokenType.STRING_TOKEN;
|
||||
export const isAutoIdentToken = (token: CSSValue): token is AutoIdentToken => isIdentWithValue(token, 'auto');
|
||||
export const isIdentWithValue = (token: CSSValue, value: string): boolean =>
|
||||
isIdentToken(token) && token.value === value;
|
||||
|
||||
|
@ -97,6 +97,11 @@ export interface DimensionToken extends IToken {
|
||||
number: number;
|
||||
}
|
||||
|
||||
export interface AutoIdentToken extends IToken {
|
||||
type: TokenType.IDENT_TOKEN;
|
||||
value: 'auto';
|
||||
}
|
||||
|
||||
export interface UnicodeRangeToken extends IToken {
|
||||
type: TokenType.UNICODE_RANGE_TOKEN;
|
||||
start: number;
|
||||
|
@ -1,8 +1,9 @@
|
||||
import {ElementContainer} from '../dom/element-container';
|
||||
import {getAbsoluteValue, getAbsoluteValueForTuple, getAbsoluteValueForDimension} from '../css/types/length-percentage';
|
||||
import {getAbsoluteValue, getAbsoluteValueForDimension, getAbsoluteValueForTuple} from '../css/types/length-percentage';
|
||||
import {Vector} from './vector';
|
||||
import {BezierCurve} from './bezier-curve';
|
||||
import {Path} from './path';
|
||||
import {TokenType} from '../css/syntax/tokenizer';
|
||||
|
||||
export class BoundCurves {
|
||||
readonly topLeftBorderDoubleOuterBox: Path;
|
||||
@ -76,16 +77,19 @@ export class BoundCurves {
|
||||
const paddingBottom = getAbsoluteValue(styles.paddingBottom, element.bounds.width);
|
||||
const paddingLeft = getAbsoluteValue(styles.paddingLeft, element.bounds.width);
|
||||
|
||||
let rectClipTop = 0;
|
||||
let rectClipRight = 0;
|
||||
let rectClipBottom = 0;
|
||||
let rectClipLeft = 0;
|
||||
if (styles.clip) {
|
||||
rectClipTop = getAbsoluteValueForDimension(styles.clip.top);
|
||||
rectClipRight = getAbsoluteValueForDimension(styles.clip.right);
|
||||
rectClipBottom = getAbsoluteValueForDimension(styles.clip.bottom);
|
||||
rectClipLeft = getAbsoluteValueForDimension(styles.clip.left);
|
||||
}
|
||||
const rectClipTop =
|
||||
styles.clip?.top.type == TokenType.DIMENSION_TOKEN ? getAbsoluteValueForDimension(styles.clip.top) : 0;
|
||||
const rectClipLeft =
|
||||
styles.clip?.left.type == TokenType.DIMENSION_TOKEN ? getAbsoluteValueForDimension(styles.clip.left) : 0;
|
||||
|
||||
const rectClipBottom =
|
||||
styles.clip?.bottom.type == TokenType.DIMENSION_TOKEN
|
||||
? getAbsoluteValueForDimension(styles.clip.bottom)
|
||||
: bounds.height;
|
||||
const rectClipRight =
|
||||
styles.clip?.right.type == TokenType.DIMENSION_TOKEN
|
||||
? getAbsoluteValueForDimension(styles.clip.right)
|
||||
: bounds.width;
|
||||
|
||||
this.topLeftBorderDoubleOuterBox =
|
||||
tlh > 0 || tlv > 0
|
||||
|
@ -45,5 +45,13 @@
|
||||
<div style="clip: rect(0px, 400px, 50px, 200px); position: absolute; top: 500px; left: 500px; border-radius: 100%; overflow: hidden;">Some inline text <span> followed by text in span </span> followed by more inline text.
|
||||
<p>Then a block level element.</p>
|
||||
Then more inline text.</div>
|
||||
|
||||
<div style="clip: rect(auto, auto, auto, 30px); position: absolute; top: 750px;">Some inline text <span> followed by text in span </span> followed by more inline text.
|
||||
<p>Then a block level element.</p>
|
||||
Then more inline text.</div>
|
||||
|
||||
<div style="clip: auto; position: absolute; top: 750px; left: 500px;">Some inline text <span> followed by text in span </span> followed by more inline text.
|
||||
<p>Then a block level element.</p>
|
||||
Then more inline text.</div>
|
||||
</body>
|
||||
</html>
|
||||
|
Loading…
Reference in New Issue
Block a user