diff --git a/.github/workflows/build_test.yml b/.github/workflows/build_test.yml index 77b7f94644..6797a9f0e0 100644 --- a/.github/workflows/build_test.yml +++ b/.github/workflows/build_test.yml @@ -34,7 +34,6 @@ jobs: runs-on: ubuntu-22.04 name: Build JS packages needs: check_bun_lock - if: needs.check_bun_lock.outputs.bun_lock_changed == 'true' steps: - uses: actions/checkout@v4 - name: Setup Bun @@ -49,8 +48,10 @@ jobs: - name: Install dependencies run: bun install - name: bun build + if: needs.check_bun_lock.outputs.bun_lock_changed == 'true' run: bun run --bun build - uses: actions/upload-artifact@v4 + if: needs.check_bun_lock.outputs.bun_lock_changed == 'true' with: name: javascript-bundles path: vendor/javascript @@ -59,7 +60,6 @@ jobs: permissions: contents: read needs: [check_bun_lock, build_javascript] - if: ${{ success('check_bun_lock') && !failure('build_javascript') }} runs-on: ubuntu-22.04 strategy: fail-fast: false diff --git a/app/javascript/alchemy_admin/image_cropper.js b/app/javascript/alchemy_admin/image_cropper.js index 3466e2875f..ee635c071a 100644 --- a/app/javascript/alchemy_admin/image_cropper.js +++ b/app/javascript/alchemy_admin/image_cropper.js @@ -6,25 +6,19 @@ export default class ImageCropper { #cropFromField = null #cropSizeField = null - constructor( - image, - minSize, - defaultBox, - aspectRatio, - formFieldIds, - elementId - ) { + constructor(image, defaultBox, aspectRatio, formFieldIds, elementId) { this.image = image - this.minSize = minSize this.defaultBox = defaultBox this.aspectRatio = aspectRatio this.#cropFromField = document.getElementById(formFieldIds[0]) this.#cropSizeField = document.getElementById(formFieldIds[1]) this.elementId = elementId this.dialog = Alchemy.currentDialog() - this.dialog.options.closed = () => this.destroy() + if (this.dialog) { + this.dialog.options.closed = () => this.destroy() + this.bind() + } this.init() - this.bind() } get cropperOptions() { @@ -32,12 +26,9 @@ export default class ImageCropper { aspectRatio: this.aspectRatio, viewMode: 1, zoomable: false, - minCropBoxWidth: this.minSize && this.minSize[0], - minCropBoxHeight: this.minSize && this.minSize[1], - ready: (event) => { - const cropper = event.target.cropper - cropper.setData(this.box) - }, + checkCrossOrigin: false, // Prevent CORS issues + checkOrientation: false, // Prevent loading the image via AJAX which can cause CORS issues + data: this.box, cropend: () => { const data = this.#cropper.getData(true) this.update(data) diff --git a/app/views/alchemy/admin/crop.html.erb b/app/views/alchemy/admin/crop.html.erb index a1a6b2a36e..fb9ab17043 100644 --- a/app/views/alchemy/admin/crop.html.erb +++ b/app/views/alchemy/admin/crop.html.erb @@ -26,7 +26,6 @@ new ImageLoader(image); new ImageCropper( image, - <%= @settings[:min_size].to_json %>, <%= @settings[:default_box].to_json %>, <%= @settings[:ratio] %>, [ diff --git a/spec/javascript/alchemy_admin/image_cropper.spec.js b/spec/javascript/alchemy_admin/image_cropper.spec.js new file mode 100644 index 0000000000..d0af9b9cb8 --- /dev/null +++ b/spec/javascript/alchemy_admin/image_cropper.spec.js @@ -0,0 +1,58 @@ +import ImageCropper from "alchemy_admin/image_cropper" + +describe("ImageCropper", () => { + describe("cropperOptions", () => { + beforeEach(() => { + document.body.innerHTML = ` +
+ + +
+ ` + Alchemy.currentDialog = jest.fn() + }) + + it("is sets initial data", () => { + const image = new Image() + const cropper = new ImageCropper( + image, + {}, + 1, + ["crop_from", "crop_size"], + "element_id" + ) + expect(cropper.cropperOptions["data"]).toEqual({ + height: 480, + width: 1200, + x: 0, + y: 423 + }) + }) + + it("does not set min crop size", () => { + const image = new Image() + const cropper = new ImageCropper( + image, + {}, + 1, + ["crop_from", "crop_size"], + "element_id" + ) + expect(cropper.cropperOptions["minCropBoxWidth"]).toBeUndefined() + expect(cropper.cropperOptions["minCropBoxHeight"]).toBeUndefined() + }) + + it("prevents CORS issues", () => { + const image = new Image() + const cropper = new ImageCropper( + image, + {}, + 1, + ["crop_from", "crop_size"], + "element_id" + ) + expect(cropper.cropperOptions["checkCrossOrigin"]).toBe(false) + expect(cropper.cropperOptions["checkOrientation"]).toBe(false) + }) + }) +})