Browse Source

fix blocks' dnd and tests

Konstantinos Kaloutas 2 years ago
parent
commit
36335106b4
3 changed files with 54 additions and 44 deletions
  1. 49 18
      e2e-tests/dnd.spec.ts
  2. 5 3
      src/main/frontend/components/block.cljs
  3. 0 23
      src/main/frontend/utils.js

+ 49 - 18
e2e-tests/dnd.spec.ts

@@ -5,10 +5,36 @@ import { createRandomPage, enterNextBlock } from './utils'
 /**
  * Drag and Drop tests.
  *
- * NOTE: x = 30 is an estimation of left position of the drop target.
+ * When we drag and drop a block, it should always be moved under the target element,
+ * unless the targer is the first element of its container. In thas case, if we drop
+ * it at the top half of the target, it should be moved on top of it.
  */
 
-test('drop to left center', async ({ page }) => {
+test('drop "block b" to the upper left area of "block a", which is the first element of a container', async ({ page, block }) => {
+  await createRandomPage(page)
+
+  await block.mustFill('block a')
+  await block.enterNext()
+
+  await block.mustFill('block b')
+  await block.escapeEditing()
+
+  const bullet = page.locator('span.bullet-container >> nth=-1')
+  const where = page.locator('.ls-block >> nth=0')
+  await bullet.dragTo(where, {
+    targetPosition: {
+      x: 0,
+      y: 0
+    }
+  })
+
+  await page.keyboard.press('Escape')
+
+  const pageElem = page.locator('.page-blocks-inner')
+  await expect(pageElem).toHaveText('block b\nblock a', {useInnerText: true})
+})
+
+test('drop "block b" to the bottom left area of "block a", which is the first element of a container', async ({ page, block }) => {
   await createRandomPage(page)
 
   await page.fill('textarea >> nth=0', 'block a')
@@ -21,29 +47,31 @@ test('drop to left center', async ({ page }) => {
   const where = page.locator('.ls-block >> nth=0')
   await bullet.dragTo(where, {
     targetPosition: {
-      x: 30,
-      y: (await where.boundingBox()).height * 0.5
+      x: 0,
+      y: (await where.boundingBox())!.height * 0.75
     }
   })
 
   await page.keyboard.press('Escape')
 
   const pageElem = page.locator('.page-blocks-inner')
-  await expect(pageElem).toHaveText('block b\nblock a', {useInnerText: true})
+  await expect(pageElem).toHaveText('block a\nblock b', {useInnerText: true})
 })
 
-
-test('drop to upper left', async ({ page, block }) => {
+test('drop "block c" to the upper left area of "block b", which is the second element of a container', async ({ page, block }) => {
   await createRandomPage(page)
 
   await block.mustFill('block a')
   await block.enterNext()
 
   await block.mustFill('block b')
+  await block.enterNext()
+
+  await block.mustFill('block c')
   await block.escapeEditing()
 
   const bullet = page.locator('span.bullet-container >> nth=-1')
-  const where = page.locator('.ls-block >> nth=0')
+  const where = page.locator('.ls-block >> nth=1')
   await bullet.dragTo(where, {
     targetPosition: {
       x: 0,
@@ -54,29 +82,32 @@ test('drop to upper left', async ({ page, block }) => {
   await page.keyboard.press('Escape')
 
   const pageElem = page.locator('.page-blocks-inner')
-  await expect(pageElem).toHaveText('block b\nblock a', {useInnerText: true})
+  await expect(pageElem).toHaveText('block a\nblock b\nblock c', {useInnerText: true})
 })
 
-test('drop to bottom left', async ({ page }) => {
+test('drop "block c" to the bottom left area of "block a", which is the first element of a container', async ({ page, block }) => {
   await createRandomPage(page)
 
-  await page.fill('textarea >> nth=0', 'block a')
-  await enterNextBlock(page)
+  await block.mustFill('block a')
+  await block.enterNext()
 
-  await page.fill('textarea >> nth=0', 'block b')
-  await page.press('textarea >> nth=0', 'Escape')
+  await block.mustFill('block b')
+  await block.enterNext()
+
+  await block.mustFill('block c')
+  await block.escapeEditing()
 
   const bullet = page.locator('span.bullet-container >> nth=-1')
   const where = page.locator('.ls-block >> nth=0')
   await bullet.dragTo(where, {
     targetPosition: {
-      x: 30,
-      y: (await where.boundingBox()).height * 0.75
+      x: 0,
+      y: 0
     }
   })
 
   await page.keyboard.press('Escape')
 
   const pageElem = page.locator('.page-blocks-inner')
-  await expect(pageElem).toHaveText('block a\nblock b', {useInnerText: true})
-})
+  await expect(pageElem).toHaveText('block c\nblock a\nblock b', {useInnerText: true})
+})

+ 5 - 3
src/main/frontend/components/block.cljs

@@ -2596,13 +2596,15 @@
   (util/stop event)
   (when-not (dnd-same-block? uuid)
     (let [over-block (gdom/getElement block-id)
-          rect (utils/getOffsetRect over-block)
+          rect (.getBoundingClientRect over-block)
           element-top (gobj/get rect "top")
           element-left (gobj/get rect "left")
+          element-bottom (gobj/get rect "bottom")
+          element-height (- element-bottom element-top)
           x-offset (- (.. event -pageX) element-left)
-          cursor-top (gobj/get event "clientY")
+          y-offset (- (.. event -pageY) element-top)
           move-to-value (cond
-                          (and top? (<= (js/Math.abs (- cursor-top element-top)) 16))
+                          (and top? (<= y-offset (/ element-height 2)))
                           :top
 
                           (> x-offset 50)

+ 0 - 23
src/main/frontend/utils.js

@@ -19,29 +19,6 @@ export const closest = (target, selector) => {
   return null
 }
 
-export const getOffsetRect = (elem) => {
-  // (1)
-  const box = elem.getBoundingClientRect(),
-    body = document.body,
-    docElem = document.documentElement,
-    // (2)
-    scrollTop = window.pageYOffset || docElem.scrollTop || body.scrollTop,
-    scrollLeft = window.pageXOffset || docElem.scrollLeft || body.scrollLeft,
-
-    // (3)
-    clientTop = docElem.clientTop || body.clientTop || 0,
-    clientLeft = docElem.clientLeft || body.clientLeft || 0,
-
-    // (4)
-    top = box.top + scrollTop - clientTop,
-    left = box.left + scrollLeft - clientLeft;
-
-  return {
-    top: Math.round(top),
-    left: Math.round(left)
-  }
-}
-
 // jquery focus
 export const focus = (elem) => {
   return elem === document.activeElement &&