Skip to content

Commit 4141230

Browse files
authored
Merge pull request #8812 from google/rc/v11.2.2
release: v11.2.2
2 parents 6b42445 + ae25b32 commit 4141230

36 files changed

+1212
-780
lines changed

.github/workflows/appengine_deploy.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ jobs:
4242
path: _deploy/
4343

4444
- name: Deploy to App Engine
45-
uses: google-github-actions/[email protected].4
45+
uses: google-github-actions/[email protected].5
4646
# For parameters see:
4747
# https://github.com/google-github-actions/deploy-appengine#inputs
4848
with:

.github/workflows/assign_reviewers.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ jobs:
1616
requested-reviewer:
1717
runs-on: ubuntu-latest
1818
permissions:
19+
contents: read
1920
issues: write
2021
steps:
2122
- name: Assign requested reviewer

.github/workflows/conventional-label.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ jobs:
88
label:
99
runs-on: ubuntu-latest
1010
permissions:
11+
contents: read
1112
pull-requests: write
1213
steps:
1314
- uses: bcoe/conventional-release-labels@v1

blocks/lists.ts

Lines changed: 5 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1046,22 +1046,19 @@ blocks['lists_split'] = {
10461046

10471047
/**
10481048
* Returns the state of this block as a JSON serializable object.
1049-
* This block does not need to serialize any specific state as it is already
1050-
* encoded in the dropdown values, but must have an implementation to avoid
1051-
* the backward compatible XML mutations being serialized.
10521049
*
10531050
* @returns The state of this block.
10541051
*/
1055-
saveExtraState: function (this: SplitBlock): null {
1056-
return null;
1052+
saveExtraState: function (this: SplitBlock): {mode: string} {
1053+
return {'mode': this.getFieldValue('MODE')};
10571054
},
10581055

10591056
/**
10601057
* Applies the given state to this block.
1061-
* No extra state is needed or expected as it is already encoded in the
1062-
* dropdown values.
10631058
*/
1064-
loadExtraState: function (this: SplitBlock) {},
1059+
loadExtraState: function (this: SplitBlock, state: {mode: string}) {
1060+
this.updateType_(state['mode']);
1061+
},
10651062
};
10661063

10671064
// Register provided blocks.

core/block_animations.ts

Lines changed: 20 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -176,30 +176,38 @@ export function disconnectUiEffect(block: BlockSvg) {
176176
}
177177
// Start the animation.
178178
wobblingBlock = block;
179-
disconnectUiStep(block, magnitude, new Date());
179+
disconnectUiStep(block, magnitude, new Date(), 0);
180180
}
181181

182182
/**
183183
* Animate a brief wiggle of a disconnected block.
184184
*
185185
* @param block Block to animate.
186186
* @param magnitude Maximum degrees skew (reversed for RTL).
187-
* @param start Date of animation's start.
187+
* @param start Date of animation's start for deciding when to stop.
188+
* @param step Which step of the animation we're on.
188189
*/
189-
function disconnectUiStep(block: BlockSvg, magnitude: number, start: Date) {
190+
function disconnectUiStep(
191+
block: BlockSvg,
192+
magnitude: number,
193+
start: Date,
194+
step: number,
195+
) {
190196
const DURATION = 200; // Milliseconds.
191-
const WIGGLES = 3; // Half oscillations.
192-
193-
const ms = new Date().getTime() - start.getTime();
194-
const percent = ms / DURATION;
197+
const WIGGLES = [0.66, 1, 0.66, 0, -0.66, -1, -0.66, 0]; // Single cycle
195198

196199
let skew = '';
197-
if (percent <= 1) {
198-
const val = Math.round(
199-
Math.sin(percent * Math.PI * WIGGLES) * (1 - percent) * magnitude,
200-
);
200+
if (start.getTime() + DURATION > new Date().getTime()) {
201+
const val = Math.round(WIGGLES[step % WIGGLES.length] * magnitude);
201202
skew = `skewX(${val})`;
202-
disconnectPid = setTimeout(disconnectUiStep, 10, block, magnitude, start);
203+
disconnectPid = setTimeout(
204+
disconnectUiStep,
205+
15,
206+
block,
207+
magnitude,
208+
start,
209+
step + 1,
210+
);
203211
}
204212

205213
block

core/block_svg.ts

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -243,7 +243,7 @@ export class BlockSvg
243243
*
244244
* @returns #RRGGBB string.
245245
*/
246-
getColourSecondary(): string | undefined {
246+
getColourSecondary(): string {
247247
return this.style.colourSecondary;
248248
}
249249

@@ -252,7 +252,7 @@ export class BlockSvg
252252
*
253253
* @returns #RRGGBB string.
254254
*/
255-
getColourTertiary(): string | undefined {
255+
getColourTertiary(): string {
256256
return this.style.colourTertiary;
257257
}
258258

@@ -1172,6 +1172,15 @@ export class BlockSvg
11721172
}
11731173
}
11741174

1175+
/**
1176+
* Returns the BlockStyle object used to style this block.
1177+
*
1178+
* @returns This block's style object.
1179+
*/
1180+
getStyle(): BlockStyle {
1181+
return this.style;
1182+
}
1183+
11751184
/**
11761185
* Move this block to the front of the visible workspace.
11771186
* <g> tags do not respect z-index so SVG renders them in the

core/bubbles/text_bubble.ts

Lines changed: 28 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ import {Bubble} from './bubble.js';
1616
* A bubble that displays non-editable text. Used by the warning icon.
1717
*/
1818
export class TextBubble extends Bubble {
19-
private paragraph: SVGTextElement;
19+
private paragraph: SVGGElement;
2020

2121
constructor(
2222
private text: string,
@@ -48,43 +48,52 @@ export class TextBubble extends Bubble {
4848
*/
4949
private stringToSvg(text: string, container: SVGGElement) {
5050
const paragraph = this.createParagraph(container);
51-
const spans = this.createSpans(paragraph, text);
51+
const fragments = this.createTextFragments(paragraph, text);
5252
if (this.workspace.RTL)
53-
this.rightAlignSpans(paragraph.getBBox().width, spans);
53+
this.rightAlignTextFragments(paragraph.getBBox().width, fragments);
5454
return paragraph;
5555
}
5656

57-
/** Creates the paragraph container for this bubble's view's spans. */
58-
private createParagraph(container: SVGGElement): SVGTextElement {
57+
/** Creates the paragraph container for this bubble's view's text fragments. */
58+
private createParagraph(container: SVGGElement): SVGGElement {
5959
return dom.createSvgElement(
60-
Svg.TEXT,
60+
Svg.G,
6161
{
6262
'class': 'blocklyText blocklyBubbleText blocklyNoPointerEvents',
63-
'y': Bubble.BORDER_WIDTH,
63+
'transform': `translate(0,${Bubble.BORDER_WIDTH})`,
64+
'style': `direction: ${this.workspace.RTL ? 'rtl' : 'ltr'}`,
6465
},
6566
container,
6667
);
6768
}
6869

69-
/** Creates the spans visualizing the text of this bubble. */
70-
private createSpans(parent: SVGTextElement, text: string): SVGTSpanElement[] {
70+
/** Creates the text fragments visualizing the text of this bubble. */
71+
private createTextFragments(
72+
parent: SVGGElement,
73+
text: string,
74+
): SVGTextElement[] {
75+
let lineNum = 1;
7176
return text.split('\n').map((line) => {
72-
const tspan = dom.createSvgElement(
73-
Svg.TSPAN,
74-
{'dy': '1em', 'x': Bubble.BORDER_WIDTH},
77+
const fragment = dom.createSvgElement(
78+
Svg.TEXT,
79+
{'y': `${lineNum}em`, 'x': Bubble.BORDER_WIDTH},
7580
parent,
7681
);
7782
const textNode = document.createTextNode(line);
78-
tspan.appendChild(textNode);
79-
return tspan;
83+
fragment.appendChild(textNode);
84+
lineNum += 1;
85+
return fragment;
8086
});
8187
}
8288

83-
/** Right aligns the given spans. */
84-
private rightAlignSpans(maxWidth: number, spans: SVGTSpanElement[]) {
85-
for (const span of spans) {
86-
span.setAttribute('text-anchor', 'end');
87-
span.setAttribute('x', `${maxWidth + Bubble.BORDER_WIDTH}`);
89+
/** Right aligns the given text fragments. */
90+
private rightAlignTextFragments(
91+
maxWidth: number,
92+
fragments: SVGTextElement[],
93+
) {
94+
for (const text of fragments) {
95+
text.setAttribute('text-anchor', 'start');
96+
text.setAttribute('x', `${maxWidth + Bubble.BORDER_WIDTH}`);
8897
}
8998
}
9099

core/clipboard.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,9 @@ function pasteFromData<T extends ICopyData>(
8383
workspace: WorkspaceSvg,
8484
coordinate?: Coordinate,
8585
): ICopyable<T> | null {
86-
workspace = workspace.getRootWorkspace() ?? workspace;
86+
workspace = workspace.isMutator
87+
? workspace
88+
: (workspace.getRootWorkspace() ?? workspace);
8789
return (globalRegistry
8890
.getObject(globalRegistry.Type.PASTER, copyData.paster, false)
8991
?.paste(copyData, workspace, coordinate) ?? null) as ICopyable<T> | null;

core/comments/rendered_workspace_comment.ts

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -208,8 +208,14 @@ export class RenderedWorkspaceComment
208208
private startGesture(e: PointerEvent) {
209209
const gesture = this.workspace.getGesture(e);
210210
if (gesture) {
211-
gesture.handleCommentStart(e, this);
212-
this.workspace.getLayerManager()?.append(this, layers.BLOCK);
211+
if (browserEvents.isTargetInput(e)) {
212+
// If the text area was the focus, don't allow this event to bubble up
213+
// and steal focus away from the editor/comment.
214+
e.stopPropagation();
215+
} else {
216+
gesture.handleCommentStart(e, this);
217+
this.workspace.getLayerManager()?.append(this, layers.BLOCK);
218+
}
213219
common.setSelected(this);
214220
}
215221
}

core/contextmenu_items.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -611,7 +611,9 @@ export function registerCommentDuplicate() {
611611
export function registerCommentCreate() {
612612
const createOption: RegistryItem = {
613613
displayText: () => Msg['ADD_COMMENT'],
614-
preconditionFn: () => 'enabled',
614+
preconditionFn: (scope: Scope) => {
615+
return scope.workspace?.isMutator ? 'hidden' : 'enabled';
616+
},
615617
callback: (scope: Scope, e: PointerEvent) => {
616618
const workspace = scope.workspace;
617619
if (!workspace) return;

0 commit comments

Comments
 (0)