diff --git a/.github/ISSUE_TEMPLATE/bug_report.yaml b/.github/ISSUE_TEMPLATE/bug_report.yaml
index d346d87af..5d92329ee 100644
--- a/.github/ISSUE_TEMPLATE/bug_report.yaml
+++ b/.github/ISSUE_TEMPLATE/bug_report.yaml
@@ -31,6 +31,15 @@ body:
1.
2.
3.
+ - type: textarea
+ id: priority
+ attributes:
+ label: Priority
+ description: Please help us understand the priority for this issue. The more information provided will help the team better assess urgency and complexity.
+ placeholder: |
+ Work effort: Is this a quick fix or will it require a significant amount of work? Is there a clear path to a solution or is further investigation required?
+ Impact: Which part of the service is impacted? How many users are experencing this issue?
+ Is there a known workaround for this issue? If so, please describe. If not, does it prevent a user from doing a core task?
- type: textarea
id: stack-trace
attributes:
diff --git a/.github/dependabot.yml b/.github/dependabot.yml
index 42f0d297a..a1882a529 100644
--- a/.github/dependabot.yml
+++ b/.github/dependabot.yml
@@ -20,6 +20,10 @@ updates:
target-branch: 'develop'
schedule:
interval: 'weekly'
+ ignore:
+ # See notes in welcome_new_contributors.yml for details on this.
+ - dependency-name: 'actions/first-interaction'
+ versions: ['*']
commit-message:
prefix: 'chore(deps)'
labels:
diff --git a/.github/workflows/appengine_deploy.yml b/.github/workflows/appengine_deploy.yml
index efc6fe941..621918329 100644
--- a/.github/workflows/appengine_deploy.yml
+++ b/.github/workflows/appengine_deploy.yml
@@ -24,7 +24,7 @@ jobs:
npm run prepareDemos
- name: Upload
- uses: actions/upload-artifact@v4
+ uses: actions/upload-artifact@v5
with:
name: appengine_files
path: _deploy/
@@ -36,13 +36,13 @@ jobs:
needs: prepare
steps:
- name: Download prepared files
- uses: actions/download-artifact@v5
+ uses: actions/download-artifact@v6
with:
name: appengine_files
path: _deploy/
- name: Deploy to App Engine
- uses: google-github-actions/deploy-appengine@v2.1.7
+ uses: google-github-actions/deploy-appengine@v3.0.1
# For parameters see:
# https://github.com/google-github-actions/deploy-appengine#inputs
with:
diff --git a/.github/workflows/assign_reviewers.yml b/.github/workflows/assign_reviewers.yml
index 850c7c805..9382d1a57 100644
--- a/.github/workflows/assign_reviewers.yml
+++ b/.github/workflows/assign_reviewers.yml
@@ -19,7 +19,7 @@ jobs:
pull-requests: write
steps:
- name: Assign requested reviewer
- uses: actions/github-script@v7
+ uses: actions/github-script@v8
with:
script: |
try {
diff --git a/.github/workflows/browser_test.yml b/.github/workflows/browser_test.yml
index c2ce99136..7b7fc4c10 100644
--- a/.github/workflows/browser_test.yml
+++ b/.github/workflows/browser_test.yml
@@ -36,7 +36,7 @@ jobs:
ssh://git@github.com/
- name: Use Node.js ${{ matrix.node-version }}
- uses: actions/setup-node@v4
+ uses: actions/setup-node@v5
with:
node-version: ${{ matrix.node-version }}
diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml
index cdec53082..c67fe9831 100644
--- a/.github/workflows/build.yml
+++ b/.github/workflows/build.yml
@@ -33,7 +33,7 @@ jobs:
ssh://git@github.com/
- name: Use Node.js ${{ matrix.node-version }}
- uses: actions/setup-node@v4
+ uses: actions/setup-node@v5
with:
node-version: ${{ matrix.node-version }}
@@ -57,7 +57,7 @@ jobs:
- uses: actions/checkout@v5
- name: Use Node.js 20.x
- uses: actions/setup-node@v4
+ uses: actions/setup-node@v5
with:
node-version: 20.x
@@ -74,7 +74,7 @@ jobs:
- uses: actions/checkout@v5
- name: Use Node.js 20.x
- uses: actions/setup-node@v4
+ uses: actions/setup-node@v5
with:
node-version: 20.x
diff --git a/.github/workflows/conventional-label.yml b/.github/workflows/conventional-label.yml
index 42dcf2664..69e5035f7 100644
--- a/.github/workflows/conventional-label.yml
+++ b/.github/workflows/conventional-label.yml
@@ -3,8 +3,30 @@ on:
types:
- opened
- edited
-name: conventional-release-labels
+name: commit lint & label
jobs:
+ lint:
+ runs-on: ubuntu-latest
+ env:
+ PR_TITLE: ${{ github.event.pull_request.title }}
+ permissions:
+ pull-requests: read
+ contents: read
+ steps:
+ - uses: actions/checkout@v5
+ with:
+ fetch-depth: 0
+ - name: Setup node
+ uses: actions/setup-node@v5
+ with:
+ node-version: lts/*
+ cache: npm
+ - name: Install dependencies
+ run: npm ci
+ - name: Check PR title
+ id: check-pr-title
+ run: echo "$PR_TITLE" | npx commitlint --verbose
+
label:
runs-on: ubuntu-latest
permissions:
diff --git a/.github/workflows/keyboard_plugin_test.yml b/.github/workflows/keyboard_plugin_test.yml
index 82d3bfa97..a064d35ad 100644
--- a/.github/workflows/keyboard_plugin_test.yml
+++ b/.github/workflows/keyboard_plugin_test.yml
@@ -37,7 +37,7 @@ jobs:
path: blockly-keyboard-experimentation
- name: Use Node.js 20.x
- uses: actions/setup-node@v4
+ uses: actions/setup-node@v5
with:
node-version: 20.x
diff --git a/.github/workflows/tag_module_cleanup.yml b/.github/workflows/tag_module_cleanup.yml
index d83d0e937..83e581b41 100644
--- a/.github/workflows/tag_module_cleanup.yml
+++ b/.github/workflows/tag_module_cleanup.yml
@@ -15,7 +15,7 @@ jobs:
# Add the type: cleanup label
runs-on: ubuntu-latest
steps:
- - uses: actions/github-script@v7
+ - uses: actions/github-script@v8
with:
script: |
// Note that pull requests are considered issues and "shared"
diff --git a/.github/workflows/welcome_new_contributors.yml b/.github/workflows/welcome_new_contributors.yml
index 4c4860c25..0f1f05c17 100644
--- a/.github/workflows/welcome_new_contributors.yml
+++ b/.github/workflows/welcome_new_contributors.yml
@@ -9,7 +9,12 @@ jobs:
permissions:
pull-requests: write
steps:
- - uses: actions/first-interaction@v3
+ # NOTE TO DEVELOPER: Per #9447 this is pinned to v1.3.0 and all updates
+ # have been disabled for it. There are some largely incompatibilities on
+ # v2 and v3 of the action that, without resolution, will break the first
+ # interaction experience for new contributors. This dependency should not
+ # be upgraded until those issues are resolved.
+ - uses: actions/first-interaction@v1.3.0
with:
repo-token: ${{ secrets.GITHUB_TOKEN }}
pr-message: >
diff --git a/README.md b/README.md
index 5a0f3b8f2..8094c4576 100644
--- a/README.md
+++ b/README.md
@@ -1,8 +1,8 @@
# Blockly
-Google's Blockly is a library that adds a visual code editor to web and mobile apps. The Blockly editor uses interlocking, graphical blocks to represent code concepts like variables, logical expressions, loops, and more. It allows users to apply programming principles without having to worry about syntax or the intimidation of a blinking cursor on the command line. All code is free and open source.
+Google's Blockly is a library that adds a visual code editor to web and mobile apps. The Blockly editor uses interlocking, graphical blocks to represent code concepts like variables, logical expressions, loops, and more. It allows users to apply programming principles without having to worry about syntax or the intimidation of a blinking cursor on the command line. All code is [free and open source](https://github.com/google/blockly/blob/develop/LICENSE).
-
+
## Getting Started with Blockly
@@ -13,13 +13,11 @@ Blockly has many resources for learning how to use the library. Start at our [Go
- [More codelabs](https://blocklycodelabs.dev/)
- [Demos and plugins](https://google.github.io/blockly-samples/)
-Help us focus our development efforts by telling us [what you are doing with
-Blockly](https://developers.google.com/blockly/registration). The questionnaire only takes
-a few minutes and will help us better support the Blockly community.
+Help us focus our development efforts by telling us [what you are doing with Blockly](https://developers.google.com/blockly/registration). The questionnaire only takes a few minutes and will help us better support the Blockly community.
### Installing Blockly
-Blockly is [available on npm](https://www.npmjs.com/package/blockly).
+Blockly is [available on npm](https://www.npmjs.com/package/blockly):
```bash
npm install blockly
@@ -34,7 +32,7 @@ For more information on installing and using Blockly, see the [Getting Started a
### blockly-samples
-We have a number of resources such as example code, demos, and plugins in another repository called [blockly-samples](https://github.com/google/blockly-samples/). A plugin is a self-contained piece of code that adds functionality to Blockly. Plugins can add fields, define themes, create renderers, and much more. For more information, see the [Plugins documentation](https://developers.google.com/blockly/guides/plugins/overview).
+We have a number of resources such as [examples](https://github.com/google/blockly-samples/tree/master/examples), [codelabs](https://github.com/google/blockly-samples/tree/master/codelabs), and [plugins](https://github.com/google/blockly-samples/tree/master/plugins) in another repository called [blockly-samples](https://github.com/google/blockly-samples). A plugin is a self-contained piece of code that adds functionality to Blockly. Plugins can add fields, define themes, create renderers, and much more. For more information, see the [Plugins documentation](https://developers.google.com/blockly/guides/programming/plugin_overview).
## Contributing to Blockly
diff --git a/blocks/procedures.ts b/blocks/procedures.ts
index 534bfba6e..b8bc4fddd 100644
--- a/blocks/procedures.ts
+++ b/blocks/procedures.ts
@@ -726,21 +726,21 @@ const PROCEDURES_MUTATORARGUMENT = {
if (sourceBlock.isInFlyout) {
return varName;
}
-
- const model = outerWs.getVariable(varName, '');
+ const variableMap = outerWs.getVariableMap();
+ const model = variableMap.getVariable(varName, '');
if (model && model.getName() !== varName) {
// Rename the variable (case change)
- outerWs.renameVariableById(model.getId(), varName);
+ variableMap.renameVariable(model, varName);
}
if (!model) {
if (this.editingInteractively) {
if (!this.editingVariable) {
- this.editingVariable = outerWs.createVariable(varName, '');
+ this.editingVariable = variableMap.createVariable(varName, '');
} else {
- outerWs.renameVariableById(this.editingVariable.getId(), varName);
+ variableMap.renameVariable(this.editingVariable, varName);
}
} else {
- outerWs.createVariable(varName, '');
+ variableMap.createVariable(varName, '');
}
}
return varName;
diff --git a/commitlint.config.mjs b/commitlint.config.mjs
new file mode 100644
index 000000000..f94497026
--- /dev/null
+++ b/commitlint.config.mjs
@@ -0,0 +1,39 @@
+/**
+ * @license
+ * Copyright 2018 Google LLC
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+/**
+ * Rules configuration for commitlint.
+ * https://commitlint.js.org/reference/rules.html#subject-full-stop
+ *
+ * Extends the conventional-commit spec at
+ * https://github.com/conventional-changelog/commitlint/tree/master/@commitlint/config-conventional
+ */
+
+export default {
+ extends: ['@commitlint/config-conventional'],
+ rules: {
+ // Warn if not in this list. Allow for judicious creativity.
+ 'type-enum': [
+ 1,
+ 'always',
+ [
+ 'build',
+ 'chore',
+ 'ci',
+ 'docs',
+ 'feat',
+ 'fix',
+ 'refactor',
+ 'release',
+ 'revert',
+ 'test',
+ ],
+ ],
+ 'subject-case': [0],
+ },
+ helpUrl:
+ 'https://developers.google.com/blockly/guides/contribute/get-started/commits',
+};
diff --git a/core/flyout_button.ts b/core/flyout_button.ts
index 607825f05..74de275a4 100644
--- a/core/flyout_button.ts
+++ b/core/flyout_button.ts
@@ -43,9 +43,11 @@ export class FlyoutButton
/** The radius of the flyout button's borders. */
static BORDER_RADIUS = 4;
+ /** The key to the function called when this button is activated. */
+ readonly callbackKey: string;
+
private readonly text: string;
private readonly position: Coordinate;
- private readonly callbackKey: string;
private readonly cssClass: string | null;
/** Mouse up event data. */
@@ -97,12 +99,13 @@ export class FlyoutButton
this.position = new Coordinate(0, 0);
- /** The key to the function called when this button is clicked. */
+ /**
+ * The key to the function called when this button is activated.
+ * Check both the uppercase and lowercase version, because the docs
+ * say `callbackKey` but the type says `callbackkey`.
+ */
this.callbackKey =
- (json as AnyDuringMigration)[
- 'callbackKey'
- ] /* Check the lower case version
- too to satisfy IE */ ||
+ (json as AnyDuringMigration)['callbackKey'] ||
(json as AnyDuringMigration)['callbackkey'];
/** If specified, a CSS class to add to this button. */
diff --git a/core/gesture.ts b/core/gesture.ts
index 4c65c1d38..fa3d8a151 100644
--- a/core/gesture.ts
+++ b/core/gesture.ts
@@ -467,6 +467,15 @@ export class Gesture {
/* opt_noCaptureIdentifier */ true,
),
);
+ this.boundEvents.push(
+ browserEvents.conditionalBind(
+ document,
+ 'pointercancel',
+ null,
+ this.handleUp.bind(this),
+ /* opt_noCaptureIdentifier */ true,
+ ),
+ );
e.preventDefault();
e.stopPropagation();
diff --git a/core/keyboard_nav/marker.ts b/core/keyboard_nav/marker.ts
index 5c2e7e946..0cd066c16 100644
--- a/core/keyboard_nav/marker.ts
+++ b/core/keyboard_nav/marker.ts
@@ -14,6 +14,7 @@
import {BlockSvg} from '../block_svg.js';
import {Field} from '../field.js';
+import {Icon} from '../icons/icon.js';
import type {IFocusableNode} from '../interfaces/i_focusable_node.js';
import {RenderedConnection} from '../rendered_connection.js';
@@ -66,6 +67,8 @@ export class Marker {
return node.getSourceBlock() as BlockSvg;
} else if (node instanceof RenderedConnection) {
return node.getSourceBlock();
+ } else if (node instanceof Icon) {
+ return node.getSourceBlock() as BlockSvg;
}
return null;
diff --git a/core/touch.ts b/core/touch.ts
index 9af3b1f94..8fb2cd229 100644
--- a/core/touch.ts
+++ b/core/touch.ts
@@ -46,7 +46,6 @@ export const TOUCH_MAP: {[key: string]: string[]} = {
'mouseup': ['pointerup', 'pointercancel'],
'touchend': ['pointerup'],
'touchcancel': ['pointercancel'],
- 'pointerup': ['pointerup', 'pointercancel'],
};
/** PID of queued long-press task. */
diff --git a/demos/minimap/icon.png b/demos/minimap/icon.png
deleted file mode 100644
index 870caa070..000000000
Binary files a/demos/minimap/icon.png and /dev/null differ
diff --git a/demos/minimap/index.html b/demos/minimap/index.html
deleted file mode 100644
index 1a8fd357d..000000000
--- a/demos/minimap/index.html
+++ /dev/null
@@ -1,91 +0,0 @@
-
-
-
-
- Blockly Demo: Minimap
-
-
-
-
-
-
-
-
-
- This is a simple demo showing how a minimap can be implemented.
-
-
-
-
-
-
-
-
- 123
-
-
-
-
- i
- j
- k
-
-
-
-
-
-
-
diff --git a/demos/minimap/minimap.js b/demos/minimap/minimap.js
deleted file mode 100644
index a4343899a..000000000
--- a/demos/minimap/minimap.js
+++ /dev/null
@@ -1,302 +0,0 @@
-/**
-
- * Copyright 2017 Google LLC
- * SPDX-License-Identifier: Apache-2.0
- */
-
-/**
- * @fileoverview JavaScript for Blockly's Minimap demo.
- */
-'use strict';
-
-/**
- * Creating a separate namespace for minimap.
- */
-var Minimap = {};
-
-/**
- * Initialize the workspace and minimap.
- * @param {!Workspace} workspace The main workspace of the user.
- * @param {!Workspace} minimap The workspace that will be used as a minimap.
- */
-Minimap.init = function(workspace, minimap) {
- this.workspace = workspace;
- this.minimap = minimap;
-
- // Adding scroll callback functionality to vScroll and hScroll just for this demo.
- // IMPORTANT: This should be changed when there is proper UI event handling
- // API available and should be handled by workspace's event listeners.
- this.workspace.scrollbar.vScroll.setHandlePosition = function(newPosition) {
- this.handlePosition_ = newPosition;
- this.svgHandle_.setAttribute(this.positionAttribute_, this.handlePosition_);
-
- // Code above is same as the original setHandlePosition function in core/scrollbar.js.
- // New code starts from here.
-
- // Get the absolutePosition.
- var absolutePosition = (this.handlePosition_ / this.ratio);
-
- // Firing the scroll change listener.
- Minimap.onScrollChange(absolutePosition, this.horizontal_);
- };
-
- // Adding call back for horizontal scroll.
- this.workspace.scrollbar.hScroll.setHandlePosition = function(newPosition) {
- this.handlePosition_ = newPosition;
- this.svgHandle_.setAttribute(this.positionAttribute_, this.handlePosition_);
-
- // Code above is same as the original setHandlePosition function in core/scrollbar.js.
- // New code starts from here.
-
- // Get the absolutePosition.
- var absolutePosition = (this.handlePosition_ / this.ratio);
-
- // Firing the scroll change listener.
- Minimap.onScrollChange(absolutePosition, this.horizontal_);
- };
-
-
- // Required to stop a positive feedback loop when user clicks minimap
- // and the scroll changes, which in turn may change minimap.
- this.disableScrollChange = false;
-
- // Listen to events on the main workspace.
- this.workspace.addChangeListener(Minimap.mirrorEvent);
-
- //Get rectangle bounding the minimap div.
- this.rect = document.getElementById('mapDiv').getBoundingClientRect();
-
- // Create a svg overlay on the top of mapDiv for the minimap.
- this.svg = Blockly.utils.dom.createSvgElement('svg', {
- 'xmlns': Blockly.utils.dom.SVG_NS,
- 'xmlns:html': Blockly.utils.dom.HTML_NS,
- 'xmlns:xlink': Blockly.utils.dom.XLINK_NS,
- 'version': '1.1',
- 'height': this.rect.bottom-this.rect.top,
- 'width': this.rect.right-this.rect.left,
- 'class': 'minimap',
- }, document.getElementById('mapDiv'));
- this.svg.style.top = this.rect.top + 'px';
- this.svg.style.left = this.rect.left + 'px';
-
- // Creating a rectangle in the minimap that represents current view.
- Blockly.utils.dom.createSvgElement('rect', {
- 'width': 100,
- 'height': 100,
- 'class': 'mapDragger'
- }, this.svg);
-
- // Rectangle in the minimap that represents current view.
- this.mapDragger = this.svg.childNodes[0];
-
- // Adding mouse events to the rectangle, to make it Draggable.
- // Using Blockly.browserEvents.bind to attach mouse/touch listeners.
- Blockly.browserEvents.bind(
- this.mapDragger, 'mousedown', null, Minimap.mousedown);
-
- //When the window change, we need to resize the minimap window.
- window.addEventListener('resize', Minimap.repositionMinimap);
-
- // Mouse up event for the minimap.
- this.svg.addEventListener('mouseup', Minimap.updateMapDragger);
-
- //Boolean to check whether I am dragging the surface or not.
- this.isDragging = false;
-};
-
-Minimap.mousedown = function(e) {
- // Using Blockly.browserEvents.bind to attach mouse/touch listeners.
- Minimap.mouseMoveBindData = Blockly.browserEvents.bind(
- document, 'mousemove', null, Minimap.mousemove);
- Minimap.mouseUpBindData =
- Blockly.browserEvents.bind(document, 'mouseup', null, Minimap.mouseup);
-
- Minimap.isDragging = true;
- e.stopPropagation();
-};
-
-Minimap.mouseup = function(e) {
- Minimap.isDragging = false;
- // Removing listeners.
- Blockly.browserEvents.unbind(Minimap.mouseUpBindData);
- Blockly.browserEvents.unbind(Minimap.mouseMoveBindData);
- Minimap.updateMapDragger(e);
- e.stopPropagation();
-};
-
-Minimap.mousemove = function(e) {
- if (Minimap.isDragging) {
- Minimap.updateMapDragger(e);
- e.stopPropagation();
- }
-};
-
-/**
- * Run non-UI events from the main workspace on the minimap.
- * @param {!Blockly.Events.Abstract} event Event that triggered in the main
- * workspace.
- */
-Minimap.mirrorEvent = function(event) {
- if (event.isUiEvent) {
- return; // Don't mirror UI events.
- }
- // Convert event to JSON. This could then be transmitted across the net.
- var json = event.toJson();
- // Convert JSON back into an event, then execute it.
- var minimapEvent = Blockly.Events.fromJson(json, Minimap.minimap);
- minimapEvent.run(true);
- Minimap.scaleMinimap();
- Minimap.setDraggerHeight();
- Minimap.setDraggerWidth();
-};
-
-/**
- * Called when window is resized. Repositions the minimap overlay.
- */
-Minimap.repositionMinimap = function() {
- Minimap.rect = document.getElementById('mapDiv').getBoundingClientRect();
- Minimap.svg.style.top = Minimap.rect.top + 'px';
- Minimap.svg.style.left = Minimap.rect.left + 'px';
-};
-
-/**
- * Updates the rectangle's height.
- */
-Minimap.setDraggerHeight = function() {
- var workspaceMetrics = Minimap.workspace.getMetrics();
- var draggerHeight = (workspaceMetrics.viewHeight / Minimap.workspace.scale) *
- Minimap.minimap.scale;
- // It's zero when first block is placed.
- if (draggerHeight === 0) {
- return;
- }
- Minimap.mapDragger.setAttribute('height', draggerHeight);
-};
-
-/**
- * Updates the rectangle's width.
- */
-Minimap.setDraggerWidth = function() {
- var workspaceMetrics = Minimap.workspace.getMetrics();
- var draggerWidth = (workspaceMetrics.viewWidth / Minimap.workspace.scale) *
- Minimap.minimap.scale;
- // It's zero when first block is placed.
- if (draggerWidth === 0) {
- return;
- }
- Minimap.mapDragger.setAttribute('width', draggerWidth);
-};
-
-
-/**
- * Updates the overall position of the viewport of the minimap by appropriately
- * using translate functions.
- */
-Minimap.scaleMinimap = function() {
- var minimapBoundingBox = Minimap.minimap.getBlocksBoundingBox();
- var workspaceBoundingBox = Minimap.workspace.getBlocksBoundingBox();
- var workspaceMetrics = Minimap.workspace.getMetrics();
- var minimapMetrics = Minimap.minimap.getMetrics();
-
- // Scaling the minimap such that all the blocks can be seen in the viewport.
- // This padding is default because this is how to scrollbar(in main workspace)
- // is implemented.
- var topPadding = (workspaceMetrics.viewHeight) * Minimap.minimap.scale /
- (2 * Minimap.workspace.scale);
- var sidePadding = (workspaceMetrics.viewWidth) * Minimap.minimap.scale /
- (2 * Minimap.workspace.scale);
-
- // If actual padding is more than half view ports height,
- // change it to actual padding.
- if ((workspaceBoundingBox.y * Minimap.workspace.scale -
- workspaceMetrics.contentTop) *
- Minimap.minimap.scale / Minimap.workspace.scale > topPadding) {
- topPadding = (workspaceBoundingBox.y * Minimap.workspace.scale -
- workspaceMetrics.contentTop) *
- Minimap.minimap.scale / Minimap.workspace.scale;
- }
-
- // If actual padding is more than half view ports height,
- // change it to actual padding.
- if ((workspaceBoundingBox.x * Minimap.workspace.scale -
- workspaceMetrics.contentLeft) *
- Minimap.minimap.scale / Minimap.workspace.scale > sidePadding) {
- sidePadding = (workspaceBoundingBox.x * Minimap.workspace.scale -
- workspaceMetrics.contentLeft) *
- Minimap.minimap.scale / Minimap.workspace.scale;
- }
-
- var scalex = (minimapMetrics.viewWidth - 2 * sidePadding) /
- minimapBoundingBox.width;
- var scaley = (minimapMetrics.viewHeight - 2 * topPadding) /
- minimapBoundingBox.height;
- Minimap.minimap.setScale(Math.min(scalex, scaley));
-
- // Translating the minimap.
- Minimap.minimap.translate(
- -minimapMetrics.contentLeft * Minimap.minimap.scale + sidePadding,
- -minimapMetrics.contentTop * Minimap.minimap.scale + topPadding);
-};
-
-/**
- * Handles the onclick event on the minimapBoundingBox.
- * Changes mapDraggers position.
- * @param {!Event} e Event from the mouse click.
- */
-Minimap.updateMapDragger = function(e) {
- var y = e.clientY;
- var x = e.clientX;
- var draggerHeight = Minimap.mapDragger.getAttribute('height');
- var draggerWidth = Minimap.mapDragger.getAttribute('width');
-
- var finalY = y - Minimap.rect.top - draggerHeight / 2;
- var finalX = x - Minimap.rect.left - draggerWidth / 2;
-
- var maxValidY = (Minimap.workspace.getMetrics().contentHeight -
- Minimap.workspace.getMetrics().viewHeight) * Minimap.minimap.scale;
- var maxValidX = (Minimap.workspace.getMetrics().contentWidth -
- Minimap.workspace.getMetrics().viewWidth) * Minimap.minimap.scale;
-
- if (y + draggerHeight / 2 > Minimap.rect.bottom) {
- finalY = Minimap.rect.bottom - Minimap.rect.top - draggerHeight;
- } else if (y < Minimap.rect.top + draggerHeight / 2) {
- finalY = 0;
- }
-
- if (x + draggerWidth / 2 > Minimap.rect.right) {
- finalX = Minimap.rect.right - Minimap.rect.left - draggerWidth;
- } else if (x < Minimap.rect.left + draggerWidth / 2) {
- finalX = 0;
- }
-
- // Do not go below lower bound of scrollbar.
- if (finalY > maxValidY) {
- finalY = maxValidY;
- }
- if (finalX > maxValidX) {
- finalX = maxValidX;
- }
- Minimap.mapDragger.setAttribute('y', finalY);
- Minimap.mapDragger.setAttribute('x', finalX);
- // Required, otherwise creates a feedback loop.
- Minimap.disableScrollChange = true;
- Minimap.workspace.scrollbar.vScroll.set((finalY * Minimap.workspace.scale) /
- Minimap.minimap.scale);
- Minimap.workspace.scrollbar.hScroll.set((finalX * Minimap.workspace.scale) /
- Minimap.minimap.scale);
- Minimap.disableScrollChange = false;
-};
-
-/**
- * Handles the onclick event on the minimapBoundingBox, parameters are passed by
- * the event handler.
- * @param {number} position This is the absolute position of the scrollbar.
- * @param {boolean} horizontal Informs if the change event if for
- * horizontal (true) or vertical (false) scrollbar.
- */
-Minimap.onScrollChange = function(position, horizontal) {
- if (!Minimap.disableScrollChange) {
- Minimap.mapDragger.setAttribute(horizontal ? 'x' : 'y',
- position * Minimap.minimap.scale / Minimap.workspace.scale);
- }
-};
diff --git a/demos/mobile/README.md b/demos/mobile/README.md
deleted file mode 100644
index 168690e55..000000000
--- a/demos/mobile/README.md
+++ /dev/null
@@ -1,53 +0,0 @@
-# Blockly on Mobile Devices
-
-This directory contains three examples of running the Blockly library on mobile
-devices. The `html/` directory is a example of configuring a webpage for touch
-devices, with a Blockly workspace that fills the screen.
-
-The `mobile/html/` is also the basis for the Android and iOS demos. Each native
-app copies this demo into the app's local resources, and required Blockly
-library files, and hosts them in an embedded WebView.
-
-Thus, developers can quickly iterate within the `mobile/html/` directory, and
-see changes in both the Android and iOS native apps.
-
-## Running the Mobile HTML Demo
-
-Before running the mobile HTML demo, you need to create some symbolic links
-in your local file system. Run the `mobile/html/ln_resources.sh` file from
-the `mobile/html/` directory. This mimics the relative locations of the
-Blockly files seen when loading the page in a native app's embedded WebView.
-
-After doing this, opening `mobile/html/index.html` should open normally,
-filling the page with one large Blockly workspace.
-
-## The Android App
-
-### Build and Run
-
-Open the `demos/mobile/android/` directory in Android Studio. The project
-files in the directory should be ready to build and run the demo in an emulator
-or connected device.
-
-### Android Copy Tasks
-
-If you edit the `mobile/html/` demo to include new files, you will need to
-update the native app project files to also copy those files.
-
-In the Android project, two Gradle tasks are responsible for the copies.
-In `mobile/android/app/build.gradle`, the tasks `copyBlocklyHtmlFile` and
-`copyBlocklyMoreFiles` configure the copy actions.
-
-## The iOS App
-
-### Build and Run
-
-Open the `demos/mobile/iOS/` directory in XCode. The project files in the
-directory should be ready to build and run the demo in a simulator or connected
-device.
-
-### iOS Copy Script
-
-The XCode project call out to `mobile/ios/cp_resources.sh` to copy the required
-HTML and related files. If you've edited the `mobile/html/` demo to require new
-files, update this script to copy these files, too.
diff --git a/demos/mobile/android/.gitignore b/demos/mobile/android/.gitignore
deleted file mode 100644
index 3ba2b2b61..000000000
--- a/demos/mobile/android/.gitignore
+++ /dev/null
@@ -1,27 +0,0 @@
-/build
-/captures
-/app/src/main/assets/blockly
-.settings
-.project
-
-# Local Settings
-local.properties
-
-# Project files
-*.komodoproject
-.gradle
-*.iml
-.idea
-
-# Build files
-*.pyc
-*.apk
-*.ap_
-*.class
-*.dex
-
-# OSX Files
-.DS_Store
-
-# Windows Files
-Thumb.db
diff --git a/demos/mobile/android/README.md b/demos/mobile/android/README.md
deleted file mode 100644
index 31f968fea..000000000
--- a/demos/mobile/android/README.md
+++ /dev/null
@@ -1,45 +0,0 @@
-# Blockly in an Android WebView
-
-This code demonstrates how to get Blockly running in an Android app by
-embedding it in a WebView.
-
-### BlocklyWebViewFragment
-
-Most of the work is done within the fragment class `BlocklyWebViewFragment`.
-This fragment instantiates the WebView, loads the HTML
-(`assets/blockly/webview.html`, copied from `demos/mobile/html/index.html`),
-and provides a few helper methods.
-
-### Copying web assets with gradle
-
-This android project copies the necessary files from the main Blockly
-repository (i.e., parent directory). In `app/build.gradle`, note the
-`copyBlocklyHtmlFile` and `copyBlocklyMoreFiles` tasks.
-
-In your own project, the HTML and related files can be placed directly in the
-`assets/blockly` directory without the copy step. However, using the copy tasks
-simplifies the synchronization with an iOS app using the same files.
-
-### Loading Block Definitions and Generator functions
-
-The `webview.html` loads the block definitions and generator functions directly
-into the page, without support or coordination with the Android classes. This
-assumes the app will always utilize the same blocks. This does not mean all
-blocks are visible to the user all the time; that is controlled by the toolbox
-and workspace files. This should accommodate almost all applications.
-
-This does mean loading your own block definitions and generators will involve
-editing the HTML, adding you own `
-
-
-
-
-
-
-
-
-
-