From 09cd56ca9414e3315662a52b29f0c71224101c5f Mon Sep 17 00:00:00 2001 From: cubiclesoft Date: Tue, 20 Mar 2018 07:04:27 -0700 Subject: [PATCH 1/2] Added prev/next navigation support for text, images, video. Fixed Firefox spurious br tag insertion issue. --- src/scripts/bases.coffee | 11 ++++++++++ src/scripts/images.coffee | 3 +++ src/scripts/text.coffee | 43 +++++++++++++++++++++++++-------------- src/scripts/videos.coffee | 3 +++ 4 files changed, 45 insertions(+), 15 deletions(-) mode change 100644 => 100755 src/scripts/bases.coffee mode change 100644 => 100755 src/scripts/images.coffee mode change 100644 => 100755 src/scripts/text.coffee mode change 100644 => 100755 src/scripts/videos.coffee diff --git a/src/scripts/bases.coffee b/src/scripts/bases.coffee old mode 100644 new mode 100755 index 96a0cb2..44cc76d --- a/src/scripts/bases.coffee +++ b/src/scripts/bases.coffee @@ -161,6 +161,12 @@ class ContentEdit.Node return @nextWithTest (node) -> node.content != undefined + nextNavigable: () -> + # Return the next node that supports a navigate property (e.g + # `ContentEdit.Text`). + return @nextWithTest (node) -> + node.navigate != undefined + nextSibling: () -> # Return the nodes next sibling index = @parent().children.indexOf(this) @@ -217,6 +223,11 @@ class ContentEdit.Node # `ContentEdit.Text`). node = @previousWithTest (node) -> node.content != undefined + previousNavigable: () -> + # Return the previous node that supports a navigate property (e.g + # `ContentEdit.Text`). + node = @previousWithTest (node) -> node.navigate != undefined + previousSibling: () -> # Return the nodes previous sibling index = @parent().children.indexOf(this) diff --git a/src/scripts/images.coffee b/src/scripts/images.coffee old mode 100644 new mode 100755 index 8bbfda9..8c6d79c --- a/src/scripts/images.coffee +++ b/src/scripts/images.coffee @@ -15,6 +15,9 @@ class ContentEdit.Image extends ContentEdit.ResizableElement size = @size() @_aspectRatio = size[1] / size[0] + # Allow image elements to be nagivated to. + @navigate = true + # Read-only properties cssTypeName: () -> diff --git a/src/scripts/text.coffee b/src/scripts/text.coffee old mode 100644 new mode 100755 index dd02c97..5754073 --- a/src/scripts/text.coffee +++ b/src/scripts/text.coffee @@ -15,6 +15,9 @@ class ContentEdit.Text extends ContentEdit.Element else @content = new HTMLString.String(content, true) + # Allow text to be nagivated to. + @navigate = true + # Read-only properties cssTypeName: () -> @@ -292,7 +295,7 @@ class ContentEdit.Text extends ContentEdit.Element _keyDelete: (ev) -> selection = ContentSelect.Range.query(@_domElement) - unless @_atEnd(selection)and selection.isCollapsed() + unless @_atEnd(selection) and selection.isCollapsed() return ev.preventDefault() @@ -312,18 +315,20 @@ class ContentEdit.Text extends ContentEdit.Element return # If we're at the start of the element and the selection is collapsed we - # should navigate to the previous text node. + # should navigate to the previous navigable node. ev.preventDefault() + ev.stopPropagation() - # Attempt to find and select the previous content element - previous = @previousContent() + # Attempt to find and select the previous navigable element + previous = @previousNavigable() if previous previous.focus() - selection = new ContentSelect.Range( - previous.content.length(), - previous.content.length() - ) - selection.select(previous.domElement()) + if previous.content != undefined + selection = new ContentSelect.Range( + previous.content.length(), + previous.content.length() + ) + selection.select(previous.domElement()) else # If no element was found this must be the last content node found # so trigger an event for external code to manage a region switch. @@ -411,15 +416,17 @@ class ContentEdit.Text extends ContentEdit.Element return # If we're at the end of the element and the selection is collapsed we - # should navigate to the next text node. + # should navigate to the next navigable node. ev.preventDefault() + ev.stopPropagation() - # Attempt to find and select the next text element - next = @nextContent() + # Attempt to find and select the next navigable element + next = @nextNavigable() if next next.focus() - selection = new ContentSelect.Range(0, 0) - selection.select(next.domElement()) + if next.content != undefined + selection = new ContentSelect.Range(0, 0) + selection.select(next.domElement()) else # If no element was found this must be the last content node found # so trigger an event for external code to manage a region switch. @@ -459,7 +466,13 @@ class ContentEdit.Text extends ContentEdit.Element _atEnd: (selection) -> # Determine if the cursor/caret starts at the end of the content - return selection.get()[0] >= @content.length() + + # Fix for Firefox occasionally appending spurious
tag to the end of the content + len = @content.length() + if len and @content.charAt(len - 1).c() == '' + len-- + + return selection.get()[0] >= len _flagIfEmpty: () -> # Flag the element as empty if there's no content diff --git a/src/scripts/videos.coffee b/src/scripts/videos.coffee old mode 100644 new mode 100755 index 4164d3d..f5a6ce5 --- a/src/scripts/videos.coffee +++ b/src/scripts/videos.coffee @@ -20,6 +20,9 @@ class ContentEdit.Video extends ContentEdit.ResizableElement size = @size() @_aspectRatio = size[1] / size[0] + # Allow video elements to be nagivated to. + @navigate = true + # Read-only properties cssTypeName: () -> From ee56b31ae83c9641bf5f80ddeaf0202d64dd62bf Mon Sep 17 00:00:00 2001 From: cubiclesoft Date: Tue, 20 Mar 2018 20:06:24 -0700 Subject: [PATCH 2/2] Fixed empty non-zero start selection issue for Firefox. --- src/scripts/text.coffee | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/src/scripts/text.coffee b/src/scripts/text.coffee index 5754073..6dab86e 100755 --- a/src/scripts/text.coffee +++ b/src/scripts/text.coffee @@ -277,7 +277,7 @@ class ContentEdit.Text extends ContentEdit.Element _keyBack: (ev) -> selection = ContentSelect.Range.query(@_domElement) - unless selection.get()[0] == 0 and selection.isCollapsed() + unless @_atStart(selection) and selection.isCollapsed() return ev.preventDefault() @@ -311,7 +311,7 @@ class ContentEdit.Text extends ContentEdit.Element _keyLeft: (ev) -> selection = ContentSelect.Range.query(@_domElement) - unless selection.get()[0] == 0 and selection.isCollapsed() + unless @_atStart(selection) and selection.isCollapsed() return # If we're at the start of the element and the selection is collapsed we @@ -464,6 +464,16 @@ class ContentEdit.Text extends ContentEdit.Element # Private methods + _atStart: (selection) -> + # Determine if the cursor/caret starts at the start of the content + + # Fix for Firefox occasionally appending spurious
tag to the end of the content + start = 0 + if @content.length() == 1 and @content.charAt(0).c() == '' + start = 1 + + return selection.get()[0] >= 0 and selection.get()[0] <= start + _atEnd: (selection) -> # Determine if the cursor/caret starts at the end of the content @@ -643,13 +653,13 @@ class ContentEdit.PreText extends ContentEdit.Text cursor = selection.get()[0] + 1 # Depending on the selection determine how best to insert the content - if selection.get()[0] == 0 and selection.isCollapsed() + if @_atStart(selection) and selection.isCollapsed() @content = new HTMLString.String('\n', true).concat(@content) else if @_atEnd(selection) and selection.isCollapsed() @content = @content.concat(new HTMLString.String('\n', true)) - else if selection.get()[0] == 0 and + else if @_atStart(selection) and selection.get()[1] == @content.length() @content = new HTMLString.String('\n', true) cursor = 0