diff --git a/src/components/ContentNode/CodeListing.vue b/src/components/ContentNode/CodeListing.vue index c7476ab4a..a58585692 100644 --- a/src/components/ContentNode/CodeListing.vue +++ b/src/components/ContentNode/CodeListing.vue @@ -25,7 +25,10 @@
[], }, + deleteHighlights: { + type: Array, + default: () => [], + }, showLineNumbers: { type: Boolean, default: () => false, }, + isLastCodeListing: { + type: Boolean, + default: () => false, + }, }, computed: { escapedContent: ({ content }) => content.map(escapeHtml), highlightedLineNumbers() { return new Set(this.highlights.map(({ line }) => line)); }, + deleteHighlightedLineNumbers() { + return new Set(this.deleteHighlights.map(({ line }) => line)); + }, syntaxNameNormalized() { // `occ` is a legacy naming convention const fallbackMap = { occ: Language.objectiveC.key.url }; @@ -101,6 +115,9 @@ export default { isHighlighted(index) { return this.highlightedLineNumbers.has(this.lineNumberFor(index)); }, + isDeleteHighlighted(index) { + return this.deleteHighlightedLineNumbers.has(this.lineNumberFor(index)); + }, // Returns the line number for the line at the given index in `content`. lineNumberFor(index) { return this.startLineNumber + index; @@ -152,6 +169,16 @@ export default { } } +.deleteHighlighted { + text-decoration-line: line-through; + background: var(--line-delete-highlight, var(--color-code-line-delete-highlight)); + border-left: $highlighted-border-width solid var(--color-code-line-delete-highlight-border); + + .code-number { + padding-left: $code-number-padding-left - $highlighted-border-width; + } +} + pre { padding: $code-listing-with-numbers-padding; display: flex; diff --git a/src/components/Tutorial/CodePreview.vue b/src/components/Tutorial/CodePreview.vue index 8ed6c8b85..e1322c6be 100644 --- a/src/components/Tutorial/CodePreview.vue +++ b/src/components/Tutorial/CodePreview.vue @@ -12,6 +12,7 @@ + 0) { + lastCode = this.content[key - 1].code; + } else { + lastCode = ''; + } + this.activeStep = key; this.visibleAsset = { code, + lastCode, media, runtimePreview, }; diff --git a/src/styles/core/colors/_dark.scss b/src/styles/core/colors/_dark.scss index 094dd0d75..9b6841246 100644 --- a/src/styles/core/colors/_dark.scss +++ b/src/styles/core/colors/_dark.scss @@ -36,6 +36,7 @@ --color-badge-default: var(--color-badge-dark-default); --color-button-background-active: #{dark-color(fill-blue)}; --color-code-line-highlight: #{change-color(dark-color(figure-blue), $alpha: 0.08)}; + --color-code-line-delete-highlight: #{change-color(dark-color(figure-red), $alpha: 0.08)}; --color-dropdown-background: var(--color-dropdown-dark-background); --color-dropdown-border: var(--color-dropdown-dark-border); --color-dropdown-option-text: var(--color-dropdown-dark-option-text); diff --git a/src/styles/core/colors/_light.scss b/src/styles/core/colors/_light.scss index 0295210d1..25f7dead4 100644 --- a/src/styles/core/colors/_light.scss +++ b/src/styles/core/colors/_light.scss @@ -76,6 +76,8 @@ --color-code-collapsible-text: var(--color-figure-gray-secondary-alt); --color-code-line-highlight: #{change-color(light-color(figure-blue), $alpha: 0.08)}; --color-code-line-highlight-border: var(--color-figure-blue); + --color-code-line-delete-highlight: #{change-color(light-color(figure-red), $alpha: 0.08)}; + --color-code-line-delete-highlight-border: var(--color-figure-red); --color-code-plain: var(--color-figure-gray); --color-dropdown-background: #{transparentize(light-color(fill), 0.2)}; --color-dropdown-border: #{light-color(fill-gray)}; diff --git a/src/utils/syntax-highlight.js b/src/utils/syntax-highlight.js index e450d22f3..d2ff53568 100644 --- a/src/utils/syntax-highlight.js +++ b/src/utils/syntax-highlight.js @@ -1,7 +1,7 @@ /** * This source file is part of the Swift.org open source project * - * Copyright (c) 2021 Apple Inc. and the Swift project authors + * Copyright (c) 2021-2023 Apple Inc. and the Swift project authors * Licensed under Apache License v2.0 with Runtime Library Exception * * See https://swift.org/LICENSE.txt for license information @@ -192,7 +192,7 @@ function duplicateMultilineNode(element) { // wrap each new line with the current element's class const result = getLines(element.innerHTML) - .reduce((all, lineText) => `${all}${lineText || '\n\n'}\n`, ''); + .reduce((all, lineText) => `${all}${lineText || ''}\n`, ''); // return a list of newly wrapped HTML elements return htmlToElements(result.trim()); diff --git a/tests/unit/utils/syntax-highlight.spec.js b/tests/unit/utils/syntax-highlight.spec.js index ebcc1b4a6..4e5258823 100644 --- a/tests/unit/utils/syntax-highlight.spec.js +++ b/tests/unit/utils/syntax-highlight.spec.js @@ -107,17 +107,11 @@ describe("syntax-highlight", () => { expect(sanitizedCode).toMatchInlineSnapshot(` let multiline = """ Needs - - - + Spaces - - - + Between - - - + Lines """ `);