mirror of https://github.com/logseq/logseq
Copy and paste html support
parent
ff06116b7f
commit
2a2d6f5abb
|
@ -15,7 +15,8 @@
|
|||
org.clojure/core.match {:mvn/version "1.0.0"}
|
||||
com.andrewmcveigh/cljs-time {:mvn/version "0.5.2"}
|
||||
cljs-drag-n-drop {:mvn/version "0.1.0"}
|
||||
borkdude/sci {:mvn/version "0.0.13-alpha.27"}
|
||||
borkdude/sci {:mvn/version "0.0.13-alpha.27"}
|
||||
hickory {:mvn/version "0.7.1"}
|
||||
}
|
||||
|
||||
:aliases {:cljs {:extra-paths ["src/dev-cljs/"]
|
||||
|
|
|
@ -28,3 +28,4 @@ dummy.fillText = function() {};
|
|||
dummy.beginPath = function() {};
|
||||
dummy.arc = function() {};
|
||||
dummy.fill = function() {};
|
||||
dummy.getData = function() {};
|
||||
|
|
|
@ -27,7 +27,8 @@
|
|||
[cljs-time.coerce :as tc]
|
||||
[cljs-drag-n-drop.core :as dnd]
|
||||
[frontend.search :as search]
|
||||
["/frontend/utils" :as utils]))
|
||||
["/frontend/utils" :as utils]
|
||||
[frontend.extensions.html-parser :as html-parser]))
|
||||
|
||||
;; TODO: refactor the state, it is already too complex.
|
||||
(defonce *last-edit-heading (atom nil))
|
||||
|
@ -556,6 +557,14 @@
|
|||
(set-last-edit-heading! (:heading/uuid heading) value)
|
||||
(handler/save-heading-if-changed! heading new-value)))
|
||||
|
||||
(defn- append-paste-doc!
|
||||
[format event]
|
||||
(when-let [html (util/get-clipboard-as-html event)]
|
||||
(let [doc-text (html-parser/parse format html)]
|
||||
(when-not (string/blank? doc-text)
|
||||
(util/stop event)
|
||||
(state/append-current-edit-content! doc-text)))))
|
||||
|
||||
(rum/defc box < rum/reactive
|
||||
(mixins/event-mixin
|
||||
(fn [state]
|
||||
|
@ -563,6 +572,8 @@
|
|||
input-id id
|
||||
input (gdom/getElement input-id)
|
||||
repo (:heading/repo heading)]
|
||||
(.addEventListener input "paste" (fn [event]
|
||||
(append-paste-doc! format event)))
|
||||
(mixins/hide-when-esc-or-outside
|
||||
state
|
||||
:on-hide
|
||||
|
@ -736,9 +747,12 @@
|
|||
:will-unmount (fn [state]
|
||||
(let [{:keys [id value format heading repo dummy?]} (get-state state)]
|
||||
(when-let [input (gdom/getElement id)]
|
||||
(.removeEventListener input "paste" (fn [event]
|
||||
(append-paste-doc! format event)))
|
||||
(dnd/unsubscribe!
|
||||
input
|
||||
:upload-images))
|
||||
:upload-images)
|
||||
)
|
||||
(clear-when-saved!))
|
||||
state)}
|
||||
[content {:keys [on-hide dummy? node format heading]
|
||||
|
|
|
@ -282,12 +282,18 @@
|
|||
(let [{:keys [url label title]} link]
|
||||
(match url
|
||||
["Search" s]
|
||||
(case (first s)
|
||||
\#
|
||||
(cond
|
||||
(= \# (first s))
|
||||
(->elem :a {:href (str "#" (anchor-link (subs s 1)))} (map-inline config label))
|
||||
;; FIXME: same headline, see more https://orgmode.org/manual/Internal-Links.html
|
||||
\*
|
||||
(= \* (first s))
|
||||
(->elem :a {:href (str "#" (anchor-link (subs s 1)))} (map-inline config label))
|
||||
|
||||
(re-find #"^https://" s)
|
||||
(->elem :a {:href s}
|
||||
(map-inline config label))
|
||||
|
||||
:else
|
||||
;; page reference
|
||||
[:span.page-reference
|
||||
[:span.text-gray-500 "[["]
|
||||
|
@ -1110,6 +1116,7 @@
|
|||
[:div.headings-container {:style {:margin-left -24}}
|
||||
(build-headings headings config)])
|
||||
|
||||
;; headers to hiccup
|
||||
(rum/defc ->hiccup < rum/reactive
|
||||
;; (mixins/perf-measure-mixin "hiccup")
|
||||
[headings config option]
|
||||
|
|
|
@ -84,6 +84,76 @@
|
|||
|
||||
"")))
|
||||
|
||||
(defn get-hr
|
||||
[format]
|
||||
(let [format (or format (keyword (state/get-preferred-format)))]
|
||||
(case format
|
||||
:org
|
||||
"-----"
|
||||
:markdown
|
||||
"---"
|
||||
"")))
|
||||
|
||||
(defn get-bold
|
||||
[format]
|
||||
(let [format (or format (keyword (state/get-preferred-format)))]
|
||||
(case format
|
||||
:org
|
||||
"*"
|
||||
:markdown
|
||||
"**"
|
||||
"")))
|
||||
|
||||
(defn get-italic
|
||||
[format]
|
||||
(let [format (or format (keyword (state/get-preferred-format)))]
|
||||
(case format
|
||||
:org
|
||||
"/"
|
||||
:markdown
|
||||
"__"
|
||||
"")))
|
||||
(defn get-underline
|
||||
[format]
|
||||
(let [format (or format (keyword (state/get-preferred-format)))]
|
||||
(case format
|
||||
:org
|
||||
"/"
|
||||
:markdown
|
||||
"__"
|
||||
"")))
|
||||
(defn get-strike-through
|
||||
[format]
|
||||
(let [format (or format (keyword (state/get-preferred-format)))]
|
||||
(case format
|
||||
:org
|
||||
"+"
|
||||
:markdown
|
||||
"~~"
|
||||
"")))
|
||||
|
||||
(defn get-highlight
|
||||
[format]
|
||||
"^^")
|
||||
|
||||
(defn get-code
|
||||
[format]
|
||||
(let [format (or format (keyword (state/get-preferred-format)))]
|
||||
(case format
|
||||
:org
|
||||
"~"
|
||||
:markdown
|
||||
"`"
|
||||
"")))
|
||||
|
||||
(defn get-subscript
|
||||
[format]
|
||||
"_")
|
||||
|
||||
(defn get-superscript
|
||||
[format]
|
||||
"^")
|
||||
|
||||
(defn default-empty-heading
|
||||
([format]
|
||||
(default-empty-heading format 2))
|
||||
|
|
|
@ -0,0 +1,223 @@
|
|||
(ns frontend.extensions.html-parser
|
||||
(:require [goog.object :as gobj]
|
||||
[hickory.core :as hickory]
|
||||
[cljs.core.match :refer-macros [match]]
|
||||
[frontend.config :as config]
|
||||
[frontend.util :as util]
|
||||
[clojure.string :as string]
|
||||
[clojure.walk :as walk]))
|
||||
|
||||
(defonce *inside-pre? (atom false))
|
||||
(defn- hiccup-without-style
|
||||
[hiccup]
|
||||
(walk/postwalk (fn [f]
|
||||
(if (map? f)
|
||||
(dissoc f :style)
|
||||
f)) hiccup))
|
||||
|
||||
(defn- export-hiccup
|
||||
[hiccup]
|
||||
(util/format "#+BEGIN_EXPORT hiccup\n%s\n#+END_EXPORT"
|
||||
|
||||
(str (hiccup-without-style hiccup))))
|
||||
|
||||
(defn hiccup->doc-inner
|
||||
[format hiccup]
|
||||
(let [transform-fn (fn [hiccup]
|
||||
(hiccup->doc-inner format hiccup))
|
||||
heading-pattern (config/get-heading-pattern format)
|
||||
map-join (fn [children] (apply str (map transform-fn children)))
|
||||
heading-transform (fn [level children]
|
||||
(str (apply str (repeat level heading-pattern))
|
||||
" "
|
||||
(->> (map transform-fn children)
|
||||
(string/join " "))
|
||||
"\n"))
|
||||
emphasis-transform (fn [tag attrs children]
|
||||
(let [pattern (cond
|
||||
(contains? #{:b :strong} tag)
|
||||
(config/get-bold format)
|
||||
(contains? #{:i :em} tag)
|
||||
(config/get-italic format)
|
||||
(contains? #{:ins} tag)
|
||||
(config/get-underline format)
|
||||
(contains? #{:del} tag)
|
||||
(config/get-strike-through format)
|
||||
(contains? #{:mark} tag)
|
||||
(config/get-highlight format)
|
||||
:else
|
||||
nil)]
|
||||
(str pattern (map-join children) pattern)))
|
||||
wrapper (fn [tag content]
|
||||
(cond
|
||||
(contains? #{:p :hr :ul :ol :dl :table :pre :blockquote :aside :canvas
|
||||
:center :figure :figcaption :fieldset :div :footer
|
||||
:header} tag)
|
||||
(str "\n\n" content "\n\n")
|
||||
|
||||
(contains? #{:thead :tr :li :dt :dd :dl} tag)
|
||||
(str content "\n")
|
||||
|
||||
:else
|
||||
content))
|
||||
single-hiccup-transform
|
||||
(fn [x]
|
||||
(do
|
||||
(cond
|
||||
(vector? x)
|
||||
(let [[tag attrs & children] x
|
||||
result (match tag
|
||||
:head nil
|
||||
:h1 (heading-transform 1 children)
|
||||
:h2 (heading-transform 2 children)
|
||||
:h3 (heading-transform 3 children)
|
||||
:h4 (heading-transform 4 children)
|
||||
:h5 (heading-transform 5 children)
|
||||
:h6 (heading-transform 6 children)
|
||||
:a (let [href (:href attrs)
|
||||
title (:title attrs)
|
||||
label (map-join children)
|
||||
has-img-tag? (re-find #"\[:img" (str x))]
|
||||
(if has-img-tag?
|
||||
(export-hiccup x)
|
||||
(case format
|
||||
:markdown (util/format "[%s](%s)" label href)
|
||||
:org (util/format "[[%s][%s]]" href label)
|
||||
nil)))
|
||||
:img (let [src (:src attrs)
|
||||
alt (:alt attrs)]
|
||||
(case format
|
||||
:markdown (util/format "![%s](%s)" alt src)
|
||||
:org (util/format "[[%s][%s]]" src alt)
|
||||
nil))
|
||||
:p (util/format "%s"
|
||||
(map-join children))
|
||||
|
||||
:hr (config/get-hr format)
|
||||
|
||||
(_ :guard #(contains? #{:b :strong
|
||||
:i :em
|
||||
:ins
|
||||
:del
|
||||
:mark} %))
|
||||
(emphasis-transform tag attrs children)
|
||||
|
||||
:code (if @*inside-pre?
|
||||
(map-join children)
|
||||
(let [pattern (config/get-code format)]
|
||||
(str " "
|
||||
(str pattern (first children) pattern)
|
||||
" ")))
|
||||
|
||||
:pre
|
||||
(do
|
||||
(reset! *inside-pre? true)
|
||||
(let [content (string/trim (doall (map-join children)))]
|
||||
(reset! *inside-pre? false)
|
||||
(case format
|
||||
:markdown (if (string/starts-with? content "```")
|
||||
content
|
||||
(str "```\n" content "\n```"))
|
||||
:org (if (string/starts-with? content "#+BEGIN_SRC")
|
||||
content
|
||||
(util/format "#+BEGIN_SRC\n%s\n#+END_SRC" content))
|
||||
nil)))
|
||||
|
||||
:blockquote
|
||||
(case format
|
||||
:markdown (str "> " (map-join children))
|
||||
:org (util/format "#+BEGIN_QUOTE\n%s\n#+END_QUOTE" (map-join children))
|
||||
nil)
|
||||
|
||||
:li
|
||||
(str "- " (map-join children))
|
||||
|
||||
:dt
|
||||
(case format
|
||||
:org (str "- " (map-join children) " ")
|
||||
:markdown (map-join children)
|
||||
nil)
|
||||
|
||||
:dd
|
||||
(case format
|
||||
:markdown (str ": " (map-join children) "\n")
|
||||
:org (str ":: " (map-join children) "\n")
|
||||
nil)
|
||||
|
||||
:thead
|
||||
(case format
|
||||
:markdown (let [columns (count (last (first children)))]
|
||||
(str
|
||||
(map-join children)
|
||||
(str "| " (string/join " | "
|
||||
(repeat columns "----"))
|
||||
" |")))
|
||||
:org (let [columns (count (last (first children)))]
|
||||
(str
|
||||
(map-join children)
|
||||
(str "|" (string/join "+"
|
||||
(repeat columns "----"))
|
||||
"|")))
|
||||
nil)
|
||||
:tr
|
||||
(str "| "
|
||||
(->> (map transform-fn children)
|
||||
(string/join " | "))
|
||||
" |")
|
||||
|
||||
(_ :guard #(contains? #{:aside :center :figure :figcaption :fieldset :footer :header} %))
|
||||
(export-hiccup x)
|
||||
|
||||
:else (map-join children)
|
||||
)]
|
||||
(wrapper tag result))
|
||||
|
||||
(string? x)
|
||||
x
|
||||
|
||||
:else
|
||||
(println "hiccup->doc error: " x))))
|
||||
result (if (vector? (first hiccup))
|
||||
(for [x hiccup]
|
||||
(single-hiccup-transform x))
|
||||
(single-hiccup-transform hiccup))]
|
||||
(apply str result)))
|
||||
|
||||
(defn hiccup->doc
|
||||
[format hiccup]
|
||||
(let [s (hiccup->doc-inner format hiccup)]
|
||||
(if (string/blank? s)
|
||||
""
|
||||
(-> s
|
||||
(string/trim)
|
||||
(string/replace "\n\n\n\n" "\n\n")
|
||||
(string/replace "\n\n\n" "\n\n")))))
|
||||
|
||||
(defn html-decode-hiccup
|
||||
[hiccup]
|
||||
(walk/postwalk (fn [f]
|
||||
(if (string? f)
|
||||
(goog.string.unescapeEntities f)
|
||||
f)) hiccup))
|
||||
|
||||
(defonce debug-hiccup (atom nil))
|
||||
(defn parse
|
||||
[format html]
|
||||
(when-not (string/blank? html)
|
||||
(let [hiccup (hickory/as-hiccup (hickory/parse html))
|
||||
decoded-hiccup (html-decode-hiccup hiccup)]
|
||||
(reset! debug-hiccup decoded-hiccup)
|
||||
(hiccup->doc format decoded-hiccup))))
|
||||
|
||||
(def img-link
|
||||
[:a {:href "https://www.markdownguide.org/book/", :style "box-sizing: border-box; color: rgb(0, 123, 255); text-decoration: none; background-color: transparent;"} [:img {:src "https://d33wubrfki0l68.cloudfront.net/cb41dd8e38b0543a305f9c56db89b46caa802263/25192/assets/images/book-cover.jpg", :class "card-img", :alt "Markdown Guide book cover", :style "box-sizing: border-box; vertical-align: middle; border-style: none; flex-shrink: 0; width: 205.75px; border-radius: calc(0.25rem - 1px);"}]])
|
||||
|
||||
(comment
|
||||
;; | Syntax | Description | Test Text |``
|
||||
;; | :--- | :----: | ---: |
|
||||
;; | Header | Title | Here's this |
|
||||
;; | Paragraph | Text | And more |
|
||||
|
||||
(def img-link
|
||||
[:a {:href "https://www.markdownguide.org/book/", :style "box-sizing: border-box; color: rgb(0, 123, 255); text-decoration: none; background-color: transparent;"} [:img {:src "https://d33wubrfki0l68.cloudfront.net/cb41dd8e38b0543a305f9c56db89b46caa802263/25192/assets/images/book-cover.jpg", :class "card-img", :alt "Markdown Guide book cover", :style "box-sizing: border-box; vertical-align: middle; border-style: none; flex-shrink: 0; width: 205.75px; border-radius: calc(0.25rem - 1px);"}]])
|
||||
)
|
|
@ -0,0 +1,5 @@
|
|||
(ns frontend.regex)
|
||||
|
||||
;; Get this from XRegExp("^\\pL+$")
|
||||
(def valid-tag-pattern
|
||||
#"^[0-9A-Za-z_\-@%ªµºÀ-ÖØ-öø-ˁˆ-ˑˠ-ˤˬˮͰ-ʹͶͷͺ-ͽͿΆΈ-ΊΌΎ-ΡΣ-ϵϷ-ҁҊ-ԯԱ-Ֆՙՠ-ֈא-תׯ-ײؠ-يٮٯٱ-ۓەۥۦۮۯۺ-ۼۿܐܒ-ܯݍ-ޥޱߊ-ߪߴߵߺࠀ-ࠕࠚࠤࠨࡀ-ࡘࡠ-ࡪࢠ-ࢴࢶ-ࢽऄ-हऽॐक़-ॡॱ-ঀঅ-ঌএঐও-নপ-রলশ-হঽৎড়ঢ়য়-ৡৰৱৼਅ-ਊਏਐਓ-ਨਪ-ਰਲਲ਼ਵਸ਼ਸਹਖ਼-ੜਫ਼ੲ-ੴઅ-ઍએ-ઑઓ-નપ-રલળવ-હઽૐૠૡૹଅ-ଌଏଐଓ-ନପ-ରଲଳଵ-ହଽଡ଼ଢ଼ୟ-ୡୱஃஅ-ஊஎ-ஐஒ-கஙசஜஞடணதந-பம-ஹௐఅ-ఌఎ-ఐఒ-నప-హఽౘ-ౚౠౡಀಅ-ಌಎ-ಐಒ-ನಪ-ಳವ-ಹಽೞೠೡೱೲഅ-ഌഎ-ഐഒ-ഺഽൎൔ-ൖൟ-ൡൺ-ൿඅ-ඖක-නඳ-රලව-ෆก-ะาำเ-ๆກຂຄຆ-ຊຌ-ຣລວ-ະາຳຽເ-ໄໆໜ-ໟༀཀ-ཇཉ-ཬྈ-ྌက-ဪဿၐ-ၕၚ-ၝၡၥၦၮ-ၰၵ-ႁႎႠ-ჅჇჍა-ჺჼ-ቈቊ-ቍቐ-ቖቘቚ-ቝበ-ኈኊ-ኍነ-ኰኲ-ኵኸ-ኾዀዂ-ዅወ-ዖዘ-ጐጒ-ጕጘ-ፚᎀ-ᎏᎠ-Ᏽᏸ-ᏽᐁ-ᙬᙯ-ᙿᚁ-ᚚᚠ-ᛪᛱ-ᛸᜀ-ᜌᜎ-ᜑᜠ-ᜱᝀ-ᝑᝠ-ᝬᝮ-ᝰក-ឳៗៜᠠ-ᡸᢀ-ᢄᢇ-ᢨᢪᢰ-ᣵᤀ-ᤞᥐ-ᥭᥰ-ᥴᦀ-ᦫᦰ-ᧉᨀ-ᨖᨠ-ᩔᪧᬅ-ᬳᭅ-ᭋᮃ-ᮠᮮᮯᮺ-ᯥᰀ-ᰣᱍ-ᱏᱚ-ᱽᲀ-ᲈᲐ-ᲺᲽ-Ჿᳩ-ᳬᳮ-ᳳᳵᳶᳺᴀ-ᶿḀ-ἕἘ-Ἕἠ-ὅὈ-Ὅὐ-ὗὙὛὝὟ-ώᾀ-ᾴᾶ-ᾼιῂ-ῄῆ-ῌῐ-ΐῖ-Ίῠ-Ῥῲ-ῴῶ-ῼⁱⁿₐ-ₜℂℇℊ-ℓℕℙ-ℝℤΩℨK-ℭℯ-ℹℼ-ℿⅅ-ⅉⅎↃↄⰀ-Ⱞⰰ-ⱞⱠ-ⳤⳫ-ⳮⳲⳳⴀ-ⴥⴧⴭⴰ-ⵧⵯⶀ-ⶖⶠ-ⶦⶨ-ⶮⶰ-ⶶⶸ-ⶾⷀ-ⷆⷈ-ⷎⷐ-ⷖⷘ-ⷞⸯ々〆〱-〵〻〼ぁ-ゖゝ-ゟァ-ヺー-ヿㄅ-ㄯㄱ-ㆎㆠ-ㆺㇰ-ㇿ㐀-䶵一-鿯ꀀ-ꒌꓐ-ꓽꔀ-ꘌꘐ-ꘟꘪꘫꙀ-ꙮꙿ-ꚝꚠ-ꛥꜗ-ꜟꜢ-ꞈꞋ-ꞿꟂ-Ᶎꟷ-ꠁꠃ-ꠅꠇ-ꠊꠌ-ꠢꡀ-ꡳꢂ-ꢳꣲ-ꣷꣻꣽꣾꤊ-ꤥꤰ-ꥆꥠ-ꥼꦄ-ꦲꧏꧠ-ꧤꧦ-ꧯꧺ-ꧾꨀ-ꨨꩀ-ꩂꩄ-ꩋꩠ-ꩶꩺꩾ-ꪯꪱꪵꪶꪹ-ꪽꫀꫂꫛ-ꫝꫠ-ꫪꫲ-ꫴꬁ-ꬆꬉ-ꬎꬑ-ꬖꬠ-ꬦꬨ-ꬮꬰ-ꭚꭜ-ꭧꭰ-ꯢ가-힣ힰ-ퟆퟋ-ퟻ豈-舘並-龎ff-stﬓ-ﬗיִײַ-ﬨשׁ-זּטּ-לּמּנּסּףּפּצּ-ﮱﯓ-ﴽﵐ-ﶏﶒ-ﷇﷰ-ﷻﹰ-ﹴﹶ-ﻼA-Za-zヲ-하-ᅦᅧ-ᅬᅭ-ᅲᅳ-ᅵ]+$")
|
|
@ -146,6 +146,25 @@
|
|||
(update-state! :editor/content (fn [m]
|
||||
(assoc m input-id value)))))
|
||||
|
||||
(defn get-edit-input-id
|
||||
[]
|
||||
(ffirst (:editor/editing? @state)))
|
||||
|
||||
(defn append-current-edit-content!
|
||||
[append-text]
|
||||
(when-not (string/blank? append-text)
|
||||
(when-let [input-id (get-edit-input-id)]
|
||||
(when-let [input (gdom/getElement input-id)]
|
||||
(let [value (gobj/get input "value")
|
||||
new-value (str value append-text)
|
||||
new-value (if (or (= (last value) " ")
|
||||
(= (last value) "\n"))
|
||||
new-value
|
||||
(str "\n" new-value))]
|
||||
(js/document.execCommand "insertText" false append-text)
|
||||
(update-state! :editor/content (fn [m]
|
||||
(assoc m input-id new-value))))))))
|
||||
|
||||
(defn get-cursor-range
|
||||
[]
|
||||
(:cursor-range @state))
|
||||
|
@ -236,10 +255,6 @@
|
|||
(fn [m]
|
||||
(and input-id {input-id true}))))
|
||||
|
||||
(defn get-edit-input-id
|
||||
[]
|
||||
(ffirst (:editor/editing? @state)))
|
||||
|
||||
(defn sub-edit-input-id
|
||||
[]
|
||||
(ffirst (util/react (rum/cursor state :editor/editing?))))
|
||||
|
|
|
@ -13,7 +13,8 @@
|
|||
[dommy.core :as d]
|
||||
[cljs-time.core :as t]
|
||||
[cljs-time.coerce :as tc]
|
||||
[cljs-time.format :as format]))
|
||||
[cljs-time.format :as format]
|
||||
[frontend.regex :as regex]))
|
||||
|
||||
(defn format
|
||||
[fmt & args]
|
||||
|
@ -664,15 +665,20 @@
|
|||
[]
|
||||
(str (rand-str 6) (rand-str 3)))
|
||||
|
||||
;; Get this from XRegExp("^\\pL+$")
|
||||
(def valid-tag-pattern
|
||||
#"^[0-9A-Za-z_\-@%ªµºÀ-ÖØ-öø-ˁˆ-ˑˠ-ˤˬˮͰ-ʹͶͷͺ-ͽͿΆΈ-ΊΌΎ-ΡΣ-ϵϷ-ҁҊ-ԯԱ-Ֆՙՠ-ֈא-תׯ-ײؠ-يٮٯٱ-ۓەۥۦۮۯۺ-ۼۿܐܒ-ܯݍ-ޥޱߊ-ߪߴߵߺࠀ-ࠕࠚࠤࠨࡀ-ࡘࡠ-ࡪࢠ-ࢴࢶ-ࢽऄ-हऽॐक़-ॡॱ-ঀঅ-ঌএঐও-নপ-রলশ-হঽৎড়ঢ়য়-ৡৰৱৼਅ-ਊਏਐਓ-ਨਪ-ਰਲਲ਼ਵਸ਼ਸਹਖ਼-ੜਫ਼ੲ-ੴઅ-ઍએ-ઑઓ-નપ-રલળવ-હઽૐૠૡૹଅ-ଌଏଐଓ-ନପ-ରଲଳଵ-ହଽଡ଼ଢ଼ୟ-ୡୱஃஅ-ஊஎ-ஐஒ-கஙசஜஞடணதந-பம-ஹௐఅ-ఌఎ-ఐఒ-నప-హఽౘ-ౚౠౡಀಅ-ಌಎ-ಐಒ-ನಪ-ಳವ-ಹಽೞೠೡೱೲഅ-ഌഎ-ഐഒ-ഺഽൎൔ-ൖൟ-ൡൺ-ൿඅ-ඖක-නඳ-රලව-ෆก-ะาำเ-ๆກຂຄຆ-ຊຌ-ຣລວ-ະາຳຽເ-ໄໆໜ-ໟༀཀ-ཇཉ-ཬྈ-ྌက-ဪဿၐ-ၕၚ-ၝၡၥၦၮ-ၰၵ-ႁႎႠ-ჅჇჍა-ჺჼ-ቈቊ-ቍቐ-ቖቘቚ-ቝበ-ኈኊ-ኍነ-ኰኲ-ኵኸ-ኾዀዂ-ዅወ-ዖዘ-ጐጒ-ጕጘ-ፚᎀ-ᎏᎠ-Ᏽᏸ-ᏽᐁ-ᙬᙯ-ᙿᚁ-ᚚᚠ-ᛪᛱ-ᛸᜀ-ᜌᜎ-ᜑᜠ-ᜱᝀ-ᝑᝠ-ᝬᝮ-ᝰក-ឳៗៜᠠ-ᡸᢀ-ᢄᢇ-ᢨᢪᢰ-ᣵᤀ-ᤞᥐ-ᥭᥰ-ᥴᦀ-ᦫᦰ-ᧉᨀ-ᨖᨠ-ᩔᪧᬅ-ᬳᭅ-ᭋᮃ-ᮠᮮᮯᮺ-ᯥᰀ-ᰣᱍ-ᱏᱚ-ᱽᲀ-ᲈᲐ-ᲺᲽ-Ჿᳩ-ᳬᳮ-ᳳᳵᳶᳺᴀ-ᶿḀ-ἕἘ-Ἕἠ-ὅὈ-Ὅὐ-ὗὙὛὝὟ-ώᾀ-ᾴᾶ-ᾼιῂ-ῄῆ-ῌῐ-ΐῖ-Ίῠ-Ῥῲ-ῴῶ-ῼⁱⁿₐ-ₜℂℇℊ-ℓℕℙ-ℝℤΩℨK-ℭℯ-ℹℼ-ℿⅅ-ⅉⅎↃↄⰀ-Ⱞⰰ-ⱞⱠ-ⳤⳫ-ⳮⳲⳳⴀ-ⴥⴧⴭⴰ-ⵧⵯⶀ-ⶖⶠ-ⶦⶨ-ⶮⶰ-ⶶⶸ-ⶾⷀ-ⷆⷈ-ⷎⷐ-ⷖⷘ-ⷞⸯ々〆〱-〵〻〼ぁ-ゖゝ-ゟァ-ヺー-ヿㄅ-ㄯㄱ-ㆎㆠ-ㆺㇰ-ㇿ㐀-䶵一-鿯ꀀ-ꒌꓐ-ꓽꔀ-ꘌꘐ-ꘟꘪꘫꙀ-ꙮꙿ-ꚝꚠ-ꛥꜗ-ꜟꜢ-ꞈꞋ-ꞿꟂ-Ᶎꟷ-ꠁꠃ-ꠅꠇ-ꠊꠌ-ꠢꡀ-ꡳꢂ-ꢳꣲ-ꣷꣻꣽꣾꤊ-ꤥꤰ-ꥆꥠ-ꥼꦄ-ꦲꧏꧠ-ꧤꧦ-ꧯꧺ-ꧾꨀ-ꨨꩀ-ꩂꩄ-ꩋꩠ-ꩶꩺꩾ-ꪯꪱꪵꪶꪹ-ꪽꫀꫂꫛ-ꫝꫠ-ꫪꫲ-ꫴꬁ-ꬆꬉ-ꬎꬑ-ꬖꬠ-ꬦꬨ-ꬮꬰ-ꭚꭜ-ꭧꭰ-ꯢ가-힣ힰ-ퟆퟋ-ퟻ豈-舘並-龎ff-stﬓ-ﬗיִײַ-ﬨשׁ-זּטּ-לּמּנּסּףּפּצּ-ﮱﯓ-ﴽﵐ-ﶏﶒ-ﷇﷰ-ﷻﹰ-ﹴﹶ-ﻼA-Za-zヲ-하-ᅦᅧ-ᅬᅭ-ᅲᅳ-ᅵ]+$")
|
||||
|
||||
(defn tag-valid?
|
||||
[tag-name]
|
||||
(re-find valid-tag-pattern tag-name))
|
||||
(re-find regex/valid-tag-pattern tag-name))
|
||||
|
||||
;; TODO: emoji, unicode alphanum, spaces, _, -
|
||||
;; (defn page-title-valid?
|
||||
;; [page-title]
|
||||
;; )
|
||||
|
||||
(defn- get-clipboard-as-html
|
||||
[event]
|
||||
(if-let [c (gobj/get event "clipboardData")]
|
||||
(.getData c "text/html")
|
||||
(if-let [c (gobj/getValueByKeys event "originalEvent" "clipboardData")]
|
||||
(.getData c "text/html")
|
||||
(if-let [c (gobj/get js/window "clipboardData")]
|
||||
(.getData c "Text")))))
|
||||
|
|
Loading…
Reference in New Issue