Compare commits

...

37 Commits

Author SHA1 Message Date
greenkeeper[bot]
bd385bb43d chore(package): update webpack to version 4.15.1 2018-07-05 14:48:32 +00:00
Andrew Sliwinski
6fe4c33365 Update TRADEMARK 2018-06-18 13:16:21 -04:00
Paul Kaplan
6035ea29d0 Merge pull request #304 from LLK/greenkeeper/scratch-svg-renderer-0.2.0-prerelease.20180613184320
Update scratch-svg-renderer to the latest version 🚀
2018-06-15 09:05:47 -04:00
greenkeeper[bot]
bdde0168ae fix(package): update scratch-svg-renderer to version 0.2.0-prerelease.20180613184320 2018-06-13 20:54:04 +00:00
Paul Kaplan
0d1d0d3552 Merge pull request #301 from LLK/greenkeeper/scratch-svg-renderer-0.2.0-prerelease.20180605154326
Update scratch-svg-renderer to the latest version 🚀
2018-06-13 15:19:27 -04:00
greenkeeper[bot]
f10f18042e fix(package): update scratch-svg-renderer to version 0.2.0-prerelease.20180605154326 2018-06-05 15:55:07 +00:00
Paul Kaplan
ebd5378936 Merge pull request #300 from paulkaplan/update-svg-renderer
Update scratch-svg-renderer
2018-06-05 10:51:43 -04:00
Paul Kaplan
a4b8460cf0 Update scratch-svg-renderer 2018-06-05 10:26:56 -04:00
DD Liu
18d4567d66 Merge pull request #297 from fsih/updateDeps
update svg renderer
2018-05-31 17:24:49 -04:00
DD
ac8ab4e495 update svg renderer' 2018-05-31 17:11:35 -04:00
Ray Schamp
eb95e2e663 Merge pull request #272 from mzgoddard/dependents-no-boiler
Use src/index for browser entry point
2018-05-31 16:57:03 -04:00
Michael "Z" Goddard
9b869e0da7 Depend on script dependencies for downstream webpack
Downstream webpack will need any dependencies src/ depends on so it can
successfully build. Also if multiple packages being built into a larger
script share a common dependency version range, they can share the
dependency instead of duplicating it. This will save built file size,
execution time, and memory.
2018-05-31 16:49:21 -04:00
Paul Kaplan
d7e39a35d7 Merge pull request #296 from paulkaplan/fix-escaping
Remove duplicate xml escaping
2018-05-29 16:18:31 -04:00
Paul Kaplan
44c30d76ad Add snapshot test for bubble svg strings 2018-05-29 15:28:16 -04:00
Paul Kaplan
d7b26ea1be Remove duplicate xml escaping
We used to write the user string directly into the svg string, but now we are setting the `.textContent` of an actual dom node, which does the escaping for us.
2018-05-29 14:25:35 -04:00
kchadha
7f53a4a19e Merge pull request #285 from kchadha/layer-ordering
Layer ordering
2018-05-25 09:31:37 -04:00
kchadha
d8f82b21ec Merge branch 'develop' into layer-ordering 2018-05-25 09:23:02 -04:00
Karishma Chadha
13a75b6a7b Update scratch-vm dependency. 2018-05-25 09:20:16 -04:00
DD Liu
4a737352d6 Merge pull request #293 from fsih/updateDeps
Update deps
2018-05-24 18:07:23 -04:00
DD
75ad498f3c Update deps 2018-05-24 17:59:57 -04:00
Ray Schamp
de6b2dea79 Merge pull request #288 from mzgoddard/npm-files-only
Publish only src, dist, TRADEMARK, README.md, package.json, and LICENSE to npm
2018-05-24 09:04:46 -04:00
Paul Kaplan
d9f2d14306 Merge pull request #291 from paulkaplan/fix-retina-bubbles
Add an explicit width and height to fix bubbles on retina screens
2018-05-22 09:38:11 -04:00
Paul Kaplan
5009692426 Add an explicit width and height to fix bubbles on retina screens 2018-05-22 09:35:41 -04:00
DD Liu
7cd92cd125 Merge pull request #290 from fsih/updateDependencies
Update vm and svg renderer to make quirks mode optional
2018-05-21 16:04:26 -04:00
DD
88d78b5f9f Update vm and svg renderer with removing quirks mode 2018-05-21 15:53:14 -04:00
DD Liu
59413a4c2b Merge pull request #286 from fsih/removeRenderQuirks
Remove speech bubbles' reliance on svg quirks mode's _transformText
2018-05-21 14:53:21 -04:00
DD
8abffc7f0b Add viewbox to speech bubble svgs 2018-05-21 14:42:32 -04:00
Michael "Z" Goddard
9d84dfdd0e Publish specific files and folders to NPM
Users of `scratch-render` do not need the `playground` directory
installed as a npm package. If they need those directories they can
clone scratch-render and do a local build. This saves downloading 3.5MB
(`playground`) when `npm install`ing `scratch-render`.
2018-05-21 12:24:51 -04:00
Karishma Chadha
5205f9cb87 Fix up comments. 2018-05-21 09:47:57 -04:00
Karishma Chadha
f9e2fe5c80 update playground to accommodate new apis. 2018-05-20 22:11:29 -04:00
Karishma Chadha
ce4296be82 Make layer group required and get rid of explicitly ordered layer groups. 2018-05-20 22:07:38 -04:00
Karishma Chadha
2dac278f90 Fix lint errors. 2018-05-20 19:40:21 -04:00
Karishma Chadha
39ce51c6f0 Store offsets for each layer group and use full draw list for updates. 2018-05-20 18:56:39 -04:00
DD
71ecef29a2 Merge branch 'develop' into removeRenderQuirks 2018-05-16 15:16:11 -04:00
DD
528ae873d7 Remove speech bubbles' reliance on svg quirks mode's _transformText 2018-05-16 15:00:04 -04:00
Karishma Chadha
b7ac54293d @type tag does not permit descriptions. 2018-05-16 11:17:57 -04:00
Karishma Chadha
2a4f6f9f02 Add layer groups to control explicit and implicit layer ordering. 2018-05-15 22:06:27 -04:00
14 changed files with 276 additions and 77 deletions

View File

@@ -1,3 +1,4 @@
dist/*
node_modules/*
playground/*
tap-snapshots/*

View File

@@ -0,0 +1,16 @@
# Development files
.eslintrc.js
/.editorconfig
/.eslintignore
/.gitattributes
/.github
/.jsdoc.json
/.travis.yml
/test
/webpack.config.js
# Build created files
/playground
# Exclude already built packages from testing with npm pack
/scratch-render-*.{tar,tgz}

View File

@@ -1,7 +1 @@
The Scratch trademarks, including the Scratch name, logo, the Scratch Cat, Gobo, Pico, Nano, Tera and Giga graphics (the "Marks"), are property of the Massachusetts Institute of Technology (MIT), and the use of the Marks is governed by this policy.
You may use the Marks to refer to Scratch in Substantially Unmodified form.
"Substantially Unmodified" means the source code provided by MIT, possibly with minor modifications including but not limited to: bug fixes (including security), changing the locations of files for better integration with the host operating system, adding documentation, and changes to the dynamic linking of libraries.
A version is not "Substantially Unmodified" if it incorporates features not present in a release of Scratch by MIT. If you do make a substantial modification, to avoid confusion with versions of Scratch produced by MIT you must remove all Marks from your version of the software and refrain from using any of the Marks to refer to your version.
The Scratch trademarks, including the Scratch name, logo, the Scratch Cat, Gobo, Pico, Nano, Tera and Giga graphics (the "Marks"), are property of the Massachusetts Institute of Technology (MIT). Marks may not be used to endorse or promote products derived from this software without specific prior written permission.

View File

@@ -10,7 +10,7 @@
"url": "git+ssh://git@github.com/LLK/scratch-render.git"
},
"main": "./dist/node/scratch-render.js",
"browser": "./dist/web/scratch-render.js",
"browser": "./src/index.js",
"scripts": {
"build": "webpack --progress --colors",
"docs": "jsdoc -c .jsdoc.json",
@@ -35,23 +35,25 @@
"eslint": "^4.6.1",
"eslint-config-scratch": "^5.0.0",
"gh-pages": "^1.0.0",
"jsdoc": "^3.5.5",
"json": "^9.0.4",
"scratch-vm": "0.1.0-prerelease.1527254075",
"tap": "^11.0.0",
"travis-after-all": "^1.4.4",
"uglifyjs-webpack-plugin": "^1.2.5",
"webpack": "^4.15.1",
"webpack-cli": "^2.0.15",
"webpack-dev-server": "^3.1.4"
},
"dependencies": {
"grapheme-breaker": "0.3.2",
"hull.js": "0.2.10",
"ify-loader": "1.0.4",
"jsdoc": "^3.5.5",
"json": "^9.0.4",
"linebreak": "0.3.0",
"minilog": "3.1.0",
"raw-loader": "^0.5.1",
"scratch-storage": "^0.4.0",
"scratch-svg-renderer": "0.1.0-prerelease.20180514170126",
"scratch-vm": "0.1.0-prerelease.1525975472",
"tap": "^11.0.0",
"travis-after-all": "^1.4.4",
"twgl.js": "4.4.0",
"uglifyjs-webpack-plugin": "^1.2.5",
"webpack": "^4.8.0",
"webpack-cli": "^2.0.15",
"webpack-dev-server": "^3.1.4",
"xml-escape": "1.1.0"
"scratch-svg-renderer": "0.2.0-prerelease.20180613184320",
"twgl.js": "4.4.0"
}
}

View File

@@ -12,6 +12,7 @@ const ShaderManager = require('./ShaderManager');
const SVGSkin = require('./SVGSkin');
const SVGTextBubble = require('./util/svg-text-bubble');
const EffectTransform = require('./EffectTransform');
const log = require('./util/log');
const __isTouchingDrawablesPoint = twgl.v3.create();
const __candidatesBounds = new Rectangle();
@@ -120,6 +121,22 @@ class RenderWebGL extends EventEmitter {
/** @type {Array<int>} */
this._drawList = [];
// A list of layer group names in the order they should appear
// from furthest back to furthest in front.
/** @type {Array<String>} */
this._groupOrdering = [];
/**
* @typedef LayerGroup
* @property {int} groupIndex The relative position of this layer group in the group ordering
* @property {int} drawListOffset The absolute position of this layer group in the draw list
* This number gets updated as drawables get added to or deleted from the draw list.
*/
// Map of group name to layer group
/** @type {Object.<string, LayerGroup>} */
this._layerGroups = {};
/** @type {int} */
this._nextDrawableId = RenderConstants.ID_NONE + 1;
@@ -360,31 +377,100 @@ class RenderWebGL extends EventEmitter {
/**
* Create a new Drawable and add it to the scene.
* @param {string} group Layer group to add the drawable to
* @returns {int} The ID of the new Drawable.
*/
createDrawable () {
createDrawable (group) {
if (!group || !this._layerGroups.hasOwnProperty(group)) {
log.warn('Cannot create a drawable without a known layer group');
return;
}
const drawableID = this._nextDrawableId++;
const drawable = new Drawable(drawableID);
this._allDrawables[drawableID] = drawable;
this._drawList.push(drawableID);
this._addToDrawList(drawableID, group);
drawable.skin = null;
return drawableID;
}
/**
* Set the layer group ordering for the renderer.
* @param {Array<string>} groupOrdering The ordered array of layer group
* names
*/
setLayerGroupOrdering (groupOrdering) {
this._groupOrdering = groupOrdering;
for (let i = 0; i < this._groupOrdering.length; i++) {
this._layerGroups[this._groupOrdering[i]] = {
groupIndex: i,
drawListOffset: 0
};
}
}
_addToDrawList (drawableID, group) {
const currentLayerGroup = this._layerGroups[group];
const currentGroupOrderingIndex = currentLayerGroup.groupIndex;
const drawListOffset = this._endIndexForKnownLayerGroup(currentLayerGroup);
this._drawList.splice(drawListOffset, 0, drawableID);
this._updateOffsets('add', currentGroupOrderingIndex);
}
_updateOffsets (updateType, currentGroupOrderingIndex) {
for (let i = currentGroupOrderingIndex + 1; i < this._groupOrdering.length; i++) {
const laterGroupName = this._groupOrdering[i];
if (updateType === 'add') {
this._layerGroups[laterGroupName].drawListOffset++;
} else if (updateType === 'delete'){
this._layerGroups[laterGroupName].drawListOffset--;
}
}
}
// Given a layer group, return the index where it ends (non-inclusive),
// e.g. the returned index does not have a drawable from this layer group in it)
_endIndexForKnownLayerGroup (layerGroup) {
const groupIndex = layerGroup.groupIndex;
if (groupIndex === this._groupOrdering.length - 1) {
return this._drawList.length;
}
return this._layerGroups[this._groupOrdering[groupIndex + 1]].drawListOffset;
}
/**
* Destroy a Drawable, removing it from the scene.
* @param {int} drawableID The ID of the Drawable to remove.
* @param {string} group Group name that the drawable belongs to
*/
destroyDrawable (drawableID) {
destroyDrawable (drawableID, group) {
if (!group || !this._layerGroups.hasOwnProperty(group)) {
log.warn('Cannot destroy drawable without known layer group.');
return;
}
const drawable = this._allDrawables[drawableID];
drawable.dispose();
delete this._allDrawables[drawableID];
let index;
while ((index = this._drawList.indexOf(drawableID)) >= 0) {
const currentLayerGroup = this._layerGroups[group];
const endIndex = this._endIndexForKnownLayerGroup(currentLayerGroup);
let index = currentLayerGroup.drawListOffset;
while (index < endIndex) {
if (this._drawList[index] === drawableID) {
break;
}
index++;
}
if (index < endIndex) {
this._drawList.splice(index, 1);
this._updateOffsets('delete', currentLayerGroup.groupIndex);
} else {
log.warn('Could not destroy drawable that could not be found in layer group.');
return;
}
}
@@ -397,28 +483,55 @@ class RenderWebGL extends EventEmitter {
* "go to front": setDrawableOrder(id, Infinity);
* @param {int} drawableID ID of Drawable to reorder.
* @param {number} order New absolute order or relative order adjusment.
* @param {string=} group Name of layer group drawable belongs to.
* Reordering will not take place if drawable cannot be found within the bounds
* of the layer group.
* @param {boolean=} optIsRelative If set, `order` refers to a relative change.
* @param {number=} optMin If set, order constrained to be at least `optMin`.
* @return {?number} New order if changed, or null.
*/
setDrawableOrder (drawableID, order, optIsRelative, optMin) {
const oldIndex = this._drawList.indexOf(drawableID);
if (oldIndex >= 0) {
setDrawableOrder (drawableID, order, group, optIsRelative, optMin) {
if (!group || !this._layerGroups.hasOwnProperty(group)) {
log.warn('Cannot set the order of a drawable without a known layer group.');
return;
}
const currentLayerGroup = this._layerGroups[group];
const startIndex = currentLayerGroup.drawListOffset;
const endIndex = this._endIndexForKnownLayerGroup(currentLayerGroup);
let oldIndex = startIndex;
while (oldIndex < endIndex) {
if (this._drawList[oldIndex] === drawableID) {
break;
}
oldIndex++;
}
if (oldIndex < endIndex) {
// Remove drawable from the list.
const drawable = this._drawList.splice(oldIndex, 1)[0];
if (order === 0) {
return oldIndex;
}
const _ = this._drawList.splice(oldIndex, 1)[0];
// Determine new index.
let newIndex = order;
if (optIsRelative) {
newIndex += oldIndex;
}
if (optMin) {
newIndex = Math.max(newIndex, optMin);
}
newIndex = Math.max(newIndex, 0);
const possibleMin = (optMin || 0) + startIndex;
const min = (possibleMin >= startIndex && possibleMin < endIndex) ? possibleMin : startIndex;
newIndex = Math.max(newIndex, min);
newIndex = Math.min(newIndex, endIndex);
// Insert at new index.
this._drawList.splice(newIndex, 0, drawable);
return this._drawList.indexOf(drawable);
this._drawList.splice(newIndex, 0, drawableID);
return newIndex;
}
return null;
}

View File

@@ -59,11 +59,11 @@ class Silhouette {
const height = this._height = canvas.height = bitmapData.height;
const ctx = canvas.getContext('2d');
ctx.clearRect(0, 0, width, height);
ctx.drawImage(bitmapData, 0, 0, width, height);
if (!(width && height)) {
return;
}
ctx.clearRect(0, 0, width, height);
ctx.drawImage(bitmapData, 0, 0, width, height);
const imageData = ctx.getImageData(0, 0, width, height);
this._data = new Uint8ClampedArray(imageData.data.length / 4);

View File

@@ -38,15 +38,16 @@
var canvas = document.getElementById('scratch-stage');
var fudge = 90;
var renderer = new ScratchRender(canvas);
renderer.setLayerGroupOrdering(['group1']);
var drawableID = renderer.createDrawable();
var drawableID = renderer.createDrawable('group1');
renderer.updateDrawableProperties(drawableID, {
position: [0, 0],
scale: [100, 100],
direction: 90
});
var drawableID2 = renderer.createDrawable();
var drawableID2 = renderer.createDrawable('group1');
var wantBitmapSkin = false;
// Bitmap (squirrel)

4
src/util/log.js Normal file
View File

@@ -0,0 +1,4 @@
const minilog = require('minilog');
minilog.enable();
module.exports = minilog('scratch-render');

View File

@@ -1,17 +1,30 @@
const SVGTextWrapper = require('./svg-text-wrapper');
const SvgRenderer = require('scratch-svg-renderer').SVGRenderer;
const xmlescape = require('xml-escape');
const MAX_LINE_LENGTH = 170;
const MIN_WIDTH = 50;
const STROKE_WIDTH = 4;
class SVGTextBubble {
constructor () {
this.svgRenderer = new SvgRenderer();
this.svgTextWrapper = new SVGTextWrapper();
this.svgTextWrapper = new SVGTextWrapper(this.makeSvgTextElement);
this._textSizeCache = {};
}
/**
* @return {SVGElement} an SVG text node with the properties that we want for speech bubbles.
*/
makeSvgTextElement () {
const svgText = document.createElementNS('http://www.w3.org/2000/svg', 'text');
svgText.setAttribute('alignment-baseline', 'text-before-edge');
svgText.setAttribute('font-size', '14');
svgText.setAttribute('fill', '#575E75');
// TODO Do we want to use the new default sans font instead of Helvetica?
svgText.setAttribute('font-family', 'Helvetica');
return svgText;
}
_speechBubble (w, h, radius, pointsLeft) {
let pathString = `
M 0 ${radius}
@@ -45,7 +58,7 @@ class SVGTextBubble {
<path
d="${pathString}"
stroke="rgba(0, 0, 0, 0.15)"
stroke-width="4"
stroke-width="${STROKE_WIDTH}"
fill="rgba(0, 0, 0, 0.15)"
stroke-line-join="round"
/>
@@ -101,7 +114,7 @@ class SVGTextBubble {
rx="${rx}" ry="${ry}"
fill="rgba(0, 0, 0, 0.15)"
stroke="rgba(0, 0, 0, 0.15)"
stroke-width="4"
stroke-width="${STROKE_WIDTH}"
/>
<ellipse
cx="${cx}" cy="${cy}"
@@ -125,7 +138,8 @@ class SVGTextBubble {
return `
<g>
<path d="${pathString}" stroke="rgba(0, 0, 0, 0.15)" stroke-width="4" fill="rgba(0, 0, 0, 0.15)" />
<path d="${pathString}" stroke="rgba(0, 0, 0, 0.15)" stroke-width="${STROKE_WIDTH}"
fill="rgba(0, 0, 0, 0.15)" />
<path d="${pathString}" stroke="none" fill="white" />
${ellipses.join('\n')}
</g>`;
@@ -133,30 +147,38 @@ class SVGTextBubble {
_getTextSize () {
const svgString = this._wrapSvgFragment(this._textFragment());
const svgString = this._wrapSvgFragment(this._textFragment);
if (!this._textSizeCache[svgString]) {
this._textSizeCache[svgString] = this.svgRenderer.measure(svgString);
}
return this._textSizeCache[svgString];
}
_wrapSvgFragment (fragment) {
return `
<svg xmlns="http://www.w3.org/2000/svg" version="1.1">
${fragment}
</svg>
`;
_wrapSvgFragment (fragment, width, height) {
let svgString = `<svg xmlns="http://www.w3.org/2000/svg" version="1.1"`;
if (width && height) {
const fullWidth = width + STROKE_WIDTH;
const fullHeight = height + STROKE_WIDTH + 12;
svgString = `${svgString} viewBox="
${-STROKE_WIDTH / 2} ${-STROKE_WIDTH / 2} ${fullWidth} ${fullHeight}"
width="${fullWidth}" height="${fullHeight}">`;
} else {
svgString = `${svgString}>`;
}
svgString = `${svgString} ${fragment} </svg>`;
return svgString;
}
_textFragment () {
const attrs = `font-family="Helvetica, Arial, sans-serif" font-size="14px" fill="#575E75"`;
return `<text ${attrs}>${xmlescape(this.lines.join('\n'))}</text>`;
_buildTextFragment (text) {
const textNode = this.svgTextWrapper.wrapText(MAX_LINE_LENGTH, text);
const serializer = new XMLSerializer();
return serializer.serializeToString(textNode);
}
buildString (type, text, pointsLeft) {
this.type = type;
this.pointsLeft = pointsLeft;
this.lines = this.svgTextWrapper.wrapText(MAX_LINE_LENGTH, text);
this._textFragment = this._buildTextFragment(text);
let fragment = '';
@@ -170,8 +192,8 @@ class SVGTextBubble {
} else {
fragment += this._thinkBubble(fullWidth, fullHeight, radius, this.pointsLeft);
}
fragment += `<g transform="translate(${padding - x}, ${padding - y})">${this._textFragment()}</g>`;
return this._wrapSvgFragment(fragment);
fragment += `<g transform="translate(${padding - x}, ${padding - y})">${this._textFragment}</g>`;
return this._wrapSvgFragment(fragment, fullWidth, fullHeight);
}
}

View File

@@ -5,9 +5,14 @@ const TextWrapper = require('./text-wrapper');
* For use with TextWrapper.
*/
class SVGMeasurementProvider {
constructor () {
/**
* @param {function} makeTextElement - provides a text node of an SVGElement
* with the style of the text to be wrapped.
*/
constructor (makeTextElement) {
this._svgRoot = null;
this._cache = {};
this.makeTextElement = makeTextElement;
}
/**
@@ -61,16 +66,7 @@ class SVGMeasurementProvider {
const svgRoot = document.createElementNS(svgNamespace, 'svg');
const svgGroup = document.createElementNS(svgNamespace, 'g');
const svgText = document.createElementNS(svgNamespace, 'text');
// Normalize text attributes to match what the svg-renderer does.
// @TODO This code should be shared with the svg-renderer.
svgText.setAttribute('alignment-baseline', 'text-before-edge');
svgText.setAttribute('font-size', '14');
// TODO Do we want to use the new default sans font instead of Helvetica?
// This change intentionally subverts the svg-renderer auto font conversion.
svgText.setAttribute('font-family', 'Helvetica, Arial, sans-serif');
const svgText = this.makeTextElement();
// hide from the user, including screen readers
svgRoot.setAttribute('style', 'position:absolute;visibility:hidden');
@@ -99,8 +95,32 @@ class SVGMeasurementProvider {
* TextWrapper specialized for SVG text.
*/
class SVGTextWrapper extends TextWrapper {
constructor () {
super(new SVGMeasurementProvider());
/**
* @param {function} makeTextElement - provides a text node of an SVGElement
* with the style of the text to be wrapped.
*/
constructor (makeTextElement) {
super(new SVGMeasurementProvider(makeTextElement));
this.makeTextElement = makeTextElement;
}
/**
* Wrap the provided text into lines restricted to a maximum width. See Unicode Standard Annex (UAX) #14.
* @param {number} maxWidth - the maximum allowed width of a line.
* @param {string} text - the text to be wrapped. Will be split on whitespace.
* @returns {SVGElement} wrapped text node
*/
wrapText (maxWidth, text) {
const lines = super.wrapText(maxWidth, text);
const textElement = this.makeTextElement();
for (const line of lines) {
const tspanNode = document.createElementNS('http://www.w3.org/2000/svg', 'tspan');
tspanNode.setAttribute('x', '0');
tspanNode.setAttribute('dy', '1.2em');
tspanNode.textContent = line;
textElement.appendChild(tspanNode);
}
return textElement;
}
}

View File

@@ -1,5 +1,5 @@
const LineBreaker = require('linebreak');
const GraphemeBreaker = require('grapheme-breaker');
const LineBreaker = require('!ify-loader!linebreak');
const GraphemeBreaker = require('!ify-loader!grapheme-breaker');
/**
* Tell this text wrapper to use a specific measurement provider.

View File

@@ -0,0 +1,10 @@
/* IMPORTANT
* This snapshot file is auto-generated, but designed for humans.
* It should be checked into source control and tracked carefully.
* Re-generate by setting TAP_SNAPSHOT=1 and running tests.
* Make sure to inspect the output below. Do not ignore changes!
*/
'use strict'
exports[`test/integration/scratch-tests.js TAP bubble snapshot > bubble-text-snapshot 1`] = `
<text xmlns="http://www.w3.org/2000/svg" alignment-baseline="text-before-edge" font-size="14" fill="#575E75" font-family="Helvetica"><tspan x="0" dy="1.2em">&lt;e*&amp;%$&amp;^$&gt;&lt;/!abc'&gt;</tspan></text>
`

View File

@@ -1,4 +1,4 @@
/* global vm, Promise */
/* global vm, render, Promise */
const {Chromeless} = require('chromeless');
const test = require('tap').test;
const path = require('path');
@@ -101,6 +101,16 @@ const testFile = file => test(file, async t => {
}
});
const testBubbles = () => test('bubble snapshot', async t => {
const bubbleSvg = await chromeless.goto(`file://${indexHTML}`)
.evaluate(() => {
const testString = '<e*&%$&^$></!abc\'>';
return render._svgTextBubble._buildTextFragment(testString);
});
t.matchSnapshot(bubbleSvg, 'bubble-text-snapshot');
t.end();
});
// immediately invoked async function to let us wait for each test to finish before starting the next.
(async () => {
const files = fs.readdirSync(testDir())
@@ -110,6 +120,8 @@ const testFile = file => test(file, async t => {
await testFile(file);
}
await testBubbles();
// close the browser window we used
await chromeless.end();
})();

View File

@@ -21,10 +21,6 @@ const base = {
options: {
presets: [['env', {targets: {browsers: ['last 3 versions', 'Safari >= 8', 'iOS >= 8']}}]]
}
},
{
test: /node_modules[\\/](linebreak|grapheme-breaker)[\\/].*\.js$/,
loader: 'ify-loader'
}
]
},
@@ -84,6 +80,14 @@ module.exports = [
libraryTarget: 'commonjs2',
path: path.resolve('dist', 'node'),
filename: '[name].js'
},
externals: {
'!ify-loader!grapheme-breaker': 'grapheme-breaker',
'!ify-loader!linebreak': 'linebreak',
'hull.js': true,
'scratch-svg-renderer': true,
'twgl.js': true,
'xml-escape': true
}
})
];