;; This Source Code Form is subject to the terms of the Mozilla Public ;; License, v. 2.0. If a copy of the MPL was not distributed with this ;; file, You can obtain one at http://mozilla.org/MPL/2.0/. ;; ;; Copyright (c) KALEIDOS SUBSIDIARY SL (ns frontend-tests.util-text-clipboard-test "Clipboard HTML and plain text read into paste fragments. Only emphasis survives; the documents come from jsdom since the runner has no DOM." (:require ["jsdom" :refer [JSDOM]] [app.util.text.clipboard :as clipboard] [cljs.test :as t :include-macros true])) (defn- html->fragment [html] (let [window (.-window (JSDOM. "")) parser (new (.-DOMParser window))] (clipboard/document->fragment (.parseFromString parser html "text/html")))) (defn- paragraph [& runs] {:attrs {} :children (vec runs)}) ;; HTML runs carry every emphasis attr, so the source decides it. (def ^:private no-emphasis {:font-weight "400" :font-style "normal" :text-decoration "none" :text-transform "none"}) (defn- run ([text] (run text {})) ([text attrs] {:text text :attrs (merge no-emphasis attrs)})) (defn- plain-run [text] {:text text :attrs {}}) (def ^:private bold {:font-weight "700"}) (def ^:private italic {:font-style "italic"}) (def ^:private google-docs-html (str "" "" "

" "Hello " "bold" " and italic" "


" "

" "Second" "

")) (def ^:private word-html (str "" "" "" "

Plain bold

\n" "

 

\n" "

italic

" "")) (def ^:private web-page-html (str "" "

Title

" "

" "Some strong and " "a link.

" "")) (t/deftest google-docs-keeps-emphasis (t/testing "the font-weight:normal wrapper does not make the whole paste bold" (t/is (= [(paragraph (run "Hello ") (run "bold" bold) (run " and italic" italic)) (paragraph) (paragraph (run "Second"))] (html->fragment google-docs-html))))) (t/deftest word-keeps-emphasis (t/testing "Word markup and its empty   paragraphs map to plain paragraphs" (t/is (= [(paragraph (run "Plain ") (run "bold" bold)) (paragraph) (paragraph (run "italic" italic))] (html->fragment word-html))))) (t/deftest web-page-drops-fonts-colors-links-and-list-markers (t/testing "headings are bold, links lose their underline, list items become paragraphs" (t/is (= [(paragraph (run "Title" bold)) (paragraph (run "Some ") (run "strong" bold) (run " and a link.")) (paragraph (run "One")) (paragraph (run "Two"))] (html->fragment web-page-html))))) (t/deftest font-weight-threshold (t/testing "600 and above is bold" (t/is (= [(paragraph (run "semi" bold))] (html->fragment "semi")))) (t/testing "light weights are ignored" (t/is (= [(paragraph (run "light"))] (html->fragment "light"))))) (t/deftest decoration-and-transform (t/testing "underline wins over line-through, as a span holds one decoration" (t/is (= [(paragraph (run "both" {:text-decoration "underline"}))] (html->fragment "both")))) (t/testing "line-through alone is kept" (t/is (= [(paragraph (run "gone" {:text-decoration "line-through"}))] (html->fragment "gone")))) (t/testing "text-transform is kept" (t/is (= [(paragraph (run "loud" {:text-transform "uppercase"}))] (html->fragment "loud"))))) (t/deftest whitespace (t/testing "collapsible whitespace collapses and is trimmed at line ends" (t/is (= [(paragraph (run "a b"))] (html->fragment "

a \n b

")))) (t/testing "  is kept as a space" (t/is (= [(paragraph (run "a b"))] (html->fragment "

a  b

")))) (t/testing "pre keeps spaces and splits lines into paragraphs" (t/is (= [(paragraph (run "line 1")) (paragraph (run " line 2"))] (html->fragment "
line 1\n  line 2
"))))) (t/deftest line-breaks-and-empty-paragraphs (t/testing "br starts a new paragraph" (t/is (= [(paragraph (run "a")) (paragraph (run "b"))] (html->fragment "a
b")))) (t/testing "runs of empty lines collapse into one" (t/is (= [(paragraph (run "a")) (paragraph) (paragraph (run "b"))] (html->fragment "

a




b

")))) (t/testing "empty lines at both ends are dropped" (t/is (= [(paragraph (run "a"))] (html->fragment "

a



"))))) (t/deftest tables (t/testing "each row is a paragraph with its cells joined by a tab" (t/is (= [(paragraph (run "a\tb")) (paragraph (run "c\td"))] (html->fragment "
a b
cd
"))))) (t/deftest hidden-content-is-skipped (t/testing "style, script and display:none give no text" (t/is (= [(paragraph (run "shown"))] (html->fragment "

shown

hidden

")))) (t/testing "elements outside the allowlist are skipped with their text" (t/is (= [(paragraph (run "kept"))] (html->fragment "

keptcustom

")))) (t/testing "HTML without text gives no fragment" (t/is (nil? (html->fragment ""))))) (t/deftest plain-text (t/testing "each line is a paragraph and CRLF counts as one break" (t/is (= [(paragraph (plain-run "a")) (paragraph) (paragraph (plain-run "b"))] (clipboard/text->fragment "a\r\n\r\nb")))) (t/testing "empty text gives no fragment" (t/is (nil? (clipboard/text->fragment "")))))