From c63570d8bc5f465ffe2658b70992953d0c9dd35d Mon Sep 17 00:00:00 2001 From: Anthony Guo Date: Tue, 22 Sep 2015 18:12:14 -0700 Subject: [PATCH 1/2] Fix issue #2769 Add clipPath to selectionBoxLayer Add clip path behavior to the selectionBoxLayer as well as add tests for this new behavior --- plottable.js | 8 +-- src/components/dragBoxLayer.ts | 7 --- src/components/selectionBoxLayer.ts | 1 + test/components/dragBoxLayerTests.ts | 37 ------------ test/components/selectionBoxLayerTests.ts | 68 ++++++++++++++++++----- 5 files changed, 55 insertions(+), 66 deletions(-) diff --git a/plottable.js b/plottable.js index 49f164468e..ba5378951b 100644 --- a/plottable.js +++ b/plottable.js @@ -6401,6 +6401,7 @@ var Plottable; this._adjustBoundsCallback = function () { _this.render(); }; + this._clipPathEnabled = true; this._xExtent = [undefined, undefined]; this._yExtent = [undefined, undefined]; } @@ -11938,13 +11939,6 @@ var Plottable; this._resizable = false; this._movable = false; this._hasCorners = true; - /* - * Enable clipPath to hide _detectionEdge s and _detectionCorner s - * that overlap with the edge of the DragBoxLayer. This prevents the - * user's cursor from changing outside the DragBoxLayer, where they - * wouldn't be able to grab the edges or corners for resizing. - */ - this._clipPathEnabled = true; this.addClass("drag-box-layer"); this._dragInteraction = new Plottable.Interactions.Drag(); this._setUpCallbacks(); diff --git a/src/components/dragBoxLayer.ts b/src/components/dragBoxLayer.ts index c656af3011..18dca65171 100644 --- a/src/components/dragBoxLayer.ts +++ b/src/components/dragBoxLayer.ts @@ -44,13 +44,6 @@ export module Components { */ constructor() { super(); - /* - * Enable clipPath to hide _detectionEdge s and _detectionCorner s - * that overlap with the edge of the DragBoxLayer. This prevents the - * user's cursor from changing outside the DragBoxLayer, where they - * wouldn't be able to grab the edges or corners for resizing. - */ - this._clipPathEnabled = true; this.addClass("drag-box-layer"); this._dragInteraction = new Interactions.Drag(); diff --git a/src/components/selectionBoxLayer.ts b/src/components/selectionBoxLayer.ts index d4b0c0e523..6dddeff541 100644 --- a/src/components/selectionBoxLayer.ts +++ b/src/components/selectionBoxLayer.ts @@ -25,6 +25,7 @@ export module Components { this._adjustBoundsCallback = () => { this.render(); }; + this._clipPathEnabled = true; this._xExtent = [undefined, undefined]; this._yExtent = [undefined, undefined]; } diff --git a/test/components/dragBoxLayerTests.ts b/test/components/dragBoxLayerTests.ts index 3243ba9c0d..39c031eb85 100644 --- a/test/components/dragBoxLayerTests.ts +++ b/test/components/dragBoxLayerTests.ts @@ -52,43 +52,6 @@ describe("Layer Components", () => { svg.remove(); }); - it("generates the correct clipPath", () => { - dbl.renderTo(svg); - - TestMethods.verifyClipPath(dbl); - let clipRect = ( dbl)._boxContainer.select(".clip-rect"); - assert.strictEqual(TestMethods.numAttr(clipRect, "width"), SVG_WIDTH, "the clipRect has an appropriate width"); - assert.strictEqual(TestMethods.numAttr(clipRect, "height"), SVG_HEIGHT, "the clipRect has an appropriate height"); - svg.remove(); - }); - - it("updates the clipPath reference when render()-ed", () => { - if (window.history == null || window.history.replaceState == null) { // not supported on IE9 (http://caniuse.com/#feat=history) - svg.remove(); - return; - } - - dbl.renderTo(svg); - - let originalState = window.history.state; - let originalTitle = document.title; - let originalLocation = document.location.href; - window.history.replaceState(null, null, "clipPathTest"); - dbl.render(); - - let clipPathId = ( dbl)._boxContainer[0][0].firstChild.id; - let expectedPrefix = /MSIE [5-9]/.test(navigator.userAgent) ? "" : document.location.href; - expectedPrefix = expectedPrefix.replace(/#.*/g, ""); - let expectedClipPathURL = "url(" + expectedPrefix + "#" + clipPathId + ")"; - - window.history.replaceState(originalState, originalTitle, originalLocation); - - let normalizeClipPath = (s: string) => s.replace(/"/g, ""); - assert.strictEqual(normalizeClipPath(( dbl)._element.attr("clip-path")), expectedClipPathURL, - "the clipPath reference was updated"); - svg.remove(); - }); - it("can get and set the detection radius", () => { assert.strictEqual(dbl.detectionRadius(), 3, "there is a default detection radius"); assert.doesNotThrow(() => dbl.detectionRadius(4), Error, "can set detection radius before anchoring"); diff --git a/test/components/selectionBoxLayerTests.ts b/test/components/selectionBoxLayerTests.ts index 3a0dbd7489..0d6db4688e 100644 --- a/test/components/selectionBoxLayerTests.ts +++ b/test/components/selectionBoxLayerTests.ts @@ -4,14 +4,14 @@ describe("Interactive Components", () => { describe("SelectionBoxLayer", () => { describe("Basic Usage", () => { - let svgWidth = 500; - let svgHeight = 500; + let SVG_WIDTH = 500; + let SVG_HEIGHT = 500; let svg: d3.Selection; let sbl: Plottable.Components.SelectionBoxLayer; beforeEach(() => { - svg = TestMethods.generateSVG(svgWidth, svgHeight); + svg = TestMethods.generateSVG(SVG_WIDTH, SVG_HEIGHT); sbl = new Plottable.Components.SelectionBoxLayer(); }); @@ -48,6 +48,44 @@ describe("Interactive Components", () => { svg.remove(); }); + it("generates the correct clipPath", () => { + sbl.renderTo(svg); + + TestMethods.verifyClipPath(sbl); + let clipRect = ( sbl)._boxContainer.select(".clip-rect"); + assert.strictEqual(TestMethods.numAttr(clipRect, "width"), SVG_WIDTH, "the clipRect has an appropriate width"); + assert.strictEqual(TestMethods.numAttr(clipRect, "height"), SVG_HEIGHT, "the clipRect has an appropriate height"); + svg.remove(); + }); + + it("updates the clipPath reference when render()-ed", () => { + // HACKHACK not supported on IE9 (http://caniuse.com/#feat=history) + if (window.history == null || window.history.replaceState == null) { + svg.remove(); + return; + } + + sbl.renderTo(svg); + + let originalState = window.history.state; + let originalTitle = document.title; + let originalLocation = document.location.href; + window.history.replaceState(null, null, "clipPathTest"); + sbl.render(); + + let clipPathId = ( sbl)._boxContainer[0][0].firstChild.id; + let expectedPrefix = /MSIE [5-9]/.test(navigator.userAgent) ? "" : document.location.href; + expectedPrefix = expectedPrefix.replace(/#.*/g, ""); + let expectedClipPathURL = "url(" + expectedPrefix + "#" + clipPathId + ")"; + + window.history.replaceState(originalState, originalTitle, originalLocation); + + let normalizeClipPath = (s: string) => s.replace(/"/g, ""); + assert.strictEqual(normalizeClipPath(( sbl)._element.attr("clip-path")), expectedClipPathURL, + "the clipPath reference was updated"); + svg.remove(); + }); + it("can set the bounds() property", () => { let defaultBounds = sbl.bounds(); assert.strictEqual(defaultBounds.topLeft.x, 0, "top-left bound is correct (x)"); @@ -163,7 +201,7 @@ describe("Interactive Components", () => { it("can set the xScale() property", () => { let xScale = new Plottable.Scales.Linear(); xScale.domain([0, 2000]); - xScale.range([0, svgWidth]); + xScale.range([0, SVG_WIDTH]); assert.isUndefined(sbl.xScale(), "no xScale is specified by default"); assert.strictEqual(sbl.xScale(xScale), sbl, "setting the xScale returns the selection box layer"); @@ -188,7 +226,7 @@ describe("Interactive Components", () => { it("can set the data values of the left and right sides directly", () => { let xScale = new Plottable.Scales.Linear(); xScale.domain([0, 2000]); - xScale.range([0, svgWidth]); + xScale.range([0, SVG_WIDTH]); sbl.boxVisible(true); sbl.xScale(xScale); @@ -216,7 +254,7 @@ describe("Interactive Components", () => { it("uses the data values for the left and right sides if they were set last", () => { let xScale = new Plottable.Scales.Linear(); xScale.domain([0, 2000]); - xScale.range([0, svgWidth]); + xScale.range([0, SVG_WIDTH]); sbl.xScale(xScale); let bounds = { @@ -245,7 +283,7 @@ describe("Interactive Components", () => { it("updates left and right edge pixel positions if in VALUE mode and scale is switched", () => { let xScale = new Plottable.Scales.Linear(); xScale.domain([0, 2000]); - xScale.range([0, svgHeight]); + xScale.range([0, SVG_HEIGHT]); sbl.xScale(xScale); let xExtent = [100, 250]; @@ -257,7 +295,7 @@ describe("Interactive Components", () => { let xScale2 = new Plottable.Scales.ModifiedLog(); xScale2.domain([0, 1000]); - xScale2.range([0, svgHeight]); + xScale2.range([0, SVG_HEIGHT]); sbl.xScale(xScale2); assert.notStrictEqual(sbl.bounds().topLeft.x, leftPosition, "left pixel position changed"); @@ -272,7 +310,7 @@ describe("Interactive Components", () => { it("updates left and right edge pixel positions if in VALUE mode and scale updates", () => { let xScale = new Plottable.Scales.Linear(); xScale.domain([0, 2000]); - xScale.range([0, svgHeight]); + xScale.range([0, SVG_HEIGHT]); sbl.xScale(xScale); let xExtent = [100, 250]; @@ -296,7 +334,7 @@ describe("Interactive Components", () => { it("can set the yScale() property", () => { let yScale = new Plottable.Scales.Linear(); yScale.domain([0, 2000]); - yScale.range([0, svgHeight]); + yScale.range([0, SVG_HEIGHT]); assert.isUndefined(sbl.yScale(), "no yScale is specified by default"); assert.strictEqual(sbl.yScale(yScale), sbl, "setting the yScale returns the selection box layer"); @@ -322,7 +360,7 @@ describe("Interactive Components", () => { it("can set the data values of the top and bottom sides directly", () => { let yScale = new Plottable.Scales.Linear(); yScale.domain([0, 2000]); - yScale.range([0, svgHeight]); + yScale.range([0, SVG_HEIGHT]); sbl.boxVisible(true); sbl.yScale(yScale); @@ -350,7 +388,7 @@ describe("Interactive Components", () => { it("uses the data values for the top and bottom sides if they were set last", () => { let yScale = new Plottable.Scales.Linear(); yScale.domain([0, 2000]); - yScale.range([0, svgHeight]); + yScale.range([0, SVG_HEIGHT]); sbl.yScale(yScale); let bounds = { @@ -379,7 +417,7 @@ describe("Interactive Components", () => { it("updates top and bottom edge pixel positions if in VALUE mode and scale is switched", () => { let yScale = new Plottable.Scales.Linear(); yScale.domain([0, 2000]); - yScale.range([0, svgHeight]); + yScale.range([0, SVG_HEIGHT]); sbl.yScale(yScale); let yExtent = [100, 250]; @@ -391,7 +429,7 @@ describe("Interactive Components", () => { let yScale2 = new Plottable.Scales.ModifiedLog(); yScale2.domain([0, 1000]); - yScale2.range([0, svgHeight]); + yScale2.range([0, SVG_HEIGHT]); sbl.yScale(yScale2); assert.notStrictEqual(sbl.bounds().topLeft.y, topPosition, "top pixel position changed"); @@ -406,7 +444,7 @@ describe("Interactive Components", () => { it("updates top and bottom edge pixel positions if in VALUE mode and scale updates", () => { let yScale = new Plottable.Scales.Linear(); yScale.domain([0, 2000]); - yScale.range([0, svgHeight]); + yScale.range([0, SVG_HEIGHT]); sbl.yScale(yScale); let yExtent = [100, 250]; From 4f46e11eae6712dd81489b7042131e1c02cd1444 Mon Sep 17 00:00:00 2001 From: Anthony Guo Date: Wed, 23 Sep 2015 10:36:29 -0700 Subject: [PATCH 2/2] Clarify comment in selectionBoxLayerTests --- test/components/selectionBoxLayerTests.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/components/selectionBoxLayerTests.ts b/test/components/selectionBoxLayerTests.ts index 0d6db4688e..b248f7efc5 100644 --- a/test/components/selectionBoxLayerTests.ts +++ b/test/components/selectionBoxLayerTests.ts @@ -59,7 +59,7 @@ describe("Interactive Components", () => { }); it("updates the clipPath reference when render()-ed", () => { - // HACKHACK not supported on IE9 (http://caniuse.com/#feat=history) + // HACKHACK: History and history API not supported on IE9 (http://caniuse.com/#feat=history) if (window.history == null || window.history.replaceState == null) { svg.remove(); return;