Skip to content

Commit

Permalink
Merge pull request #56 from GeekTree0101/bug/VEditorKit-Support-HTML-…
Browse files Browse the repository at this point in the history
…Entitles-Handler

[BUG] Support HTML Entitles
  • Loading branch information
OhKanghoon authored Mar 4, 2019
2 parents 7d95004 + f7e8827 commit e1ad2bc
Show file tree
Hide file tree
Showing 4 changed files with 85 additions and 6 deletions.
15 changes: 15 additions & 0 deletions Example/Tests/VEditorParserSpec.swift
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,21 @@ class VEditorParserSpec: QuickSpec {
.to(beTrue())
}
}

context("HTML Entities handling test") {

it("should be success to parse with HTML entities") {

expect(parser.parseXMLToAttributedString("<p>hello &amp; world</p>").string == "hello & world")
.to(beTrue())
}

it("should be fail to parse with HTML entities") {

expect(parser.parseXMLToAttributedString("<p>hello & world</p>").string == "hello & world")
.to(beFalse())
}
}
}
}
}
44 changes: 44 additions & 0 deletions Example/Tests/VEditorXMLBuilderSpec.swift
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,50 @@ class VEditorXMLBuilderSpec: QuickSpec {
.to(equal("<content><p>hello<b>world</b>!</p><h2>headingTest</h2><p><b><i>boldItalicTest</i></b></p></content>"))
}
}

context("HTML Entities handling test") {

var testContents: [VEditorContent]!

beforeEach {
var pTagStyle = EditorRule.init().paragraphStyle("p", attributes: [:])
pTagStyle?.add(extraAttributes: [VEditorAttributeKey: ["p"]])
let textNode = NSMutableAttributedString.init()
textNode.append("hello & world".styled(with: pTagStyle!))
testContents = [textNode]
VEditorXMLBuilder.shared.encodingHTMLEntitiesExternalHandler = nil
}

it("should be success to build with default HTML entities") {
expect(VEditorXMLBuilder.shared.encodingHTMLEntitiesExternalHandler)
.to(beNil())
expect(VEditorXMLBuilder.shared.buildXML(testContents, rule: rule, packageTag: "content"))
.to(equal("<content><p>hello &amp; world</p></content>"))
}

it("should be success to build with custom HTML entities") {
VEditorXMLBuilder.shared.encodingHTMLEntitiesExternalHandler = { text -> String in
return text.replacingOccurrences(of: "&", with: "&amp;")
}

expect(VEditorXMLBuilder.shared.encodingHTMLEntitiesExternalHandler)
.toNot(beNil())
expect(VEditorXMLBuilder.shared.buildXML(testContents, rule: rule, packageTag: "content"))
.to(equal("<content><p>hello &amp; world</p></content>"))
}

it("should be fail to build with custom HTML entities") {

VEditorXMLBuilder.shared.encodingHTMLEntitiesExternalHandler = { text -> String in
return text
}

expect(VEditorXMLBuilder.shared.encodingHTMLEntitiesExternalHandler)
.toNot(beNil())
expect(VEditorXMLBuilder.shared.buildXML(testContents, rule: rule, packageTag: "content"))
.toNot(equal("<content><p>hello &amp; world</p></content>"))
}
}
}

}
Expand Down
6 changes: 2 additions & 4 deletions VEditorKit/Classes/VEditorParser.swift
Original file line number Diff line number Diff line change
Expand Up @@ -38,9 +38,7 @@ public final class VEditorParser: NSObject, XMLStyler {
public func parseXML(_ xmlString: String,
onSuccess: (([VEditorContent]) -> Void)? = nil,
onError: ((Error?) -> Void)? = nil) {
var xmlString = xmlString
.replacingOccurrences(of: "\\n", with: "\n")
.replacingOccurrences(of: "\\", with: "")
var xmlString = xmlString.convertDuplicatedBackSlashToValidParserXML()

// make newlink before block heading if needs
for blockXML in parserRule.blockStyleXMLTags {
Expand Down Expand Up @@ -193,7 +191,7 @@ internal class VEditorContentParser: NSObject, XMLParserDelegate {

func parser(_ parser: XMLParser, foundCharacters string: String) {
if self.contents.last is String {
self.contents.append(string)
self.contents.append(string.encodingHTMLEntities())
}
}

Expand Down
26 changes: 24 additions & 2 deletions VEditorKit/Classes/VEditorXMLBuilder.swift
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import BonMot
public final class VEditorXMLBuilder {

public static let shared: VEditorXMLBuilder = .init()
public var encodingHTMLEntitiesExternalHandler: ((String) -> String)?

public func buildXML(_ contents: [VEditorContent],
rule: VEditorRule,
Expand Down Expand Up @@ -73,8 +74,7 @@ public final class VEditorXMLBuilder {
using: { attributes, subRange, _ in

var content = attrText.attributedSubstring(from: subRange).string
content = content
.replacingOccurrences(of: "\"", with: "\\")
content = content.encodingHTMLEntities()

guard !content.isEmpty else { return }

Expand Down Expand Up @@ -148,4 +148,26 @@ extension String {
}
return xmlString
}

internal func encodingHTMLEntities() -> String {
guard let handler = VEditorXMLBuilder.shared.encodingHTMLEntitiesExternalHandler else {
// NOTE: default encoding HTML Entities for VEditor
// ref: https://dev.w3.org/html5/html-author/charref
return self.replacingOccurrences(of: "&", with: "&amp;")
.replacingOccurrences(of: "<", with: "&lt;")
.replacingOccurrences(of: ">", with: "&gt;")
.replacingOccurrences(of: "\"", with: "&quot;")
.replacingOccurrences(of: "'", with: "&#x27;")
.replacingOccurrences(of: "'", with: "&#x39;")
.replacingOccurrences(of: "'", with: "&#x92;")
.replacingOccurrences(of: "'", with: "&#x96;")
}

return handler(self)
}

internal func convertDuplicatedBackSlashToValidParserXML() -> String {
return self.replacingOccurrences(of: "\\n", with: "\n")
.replacingOccurrences(of: "\\", with: "")
}
}

0 comments on commit e1ad2bc

Please sign in to comment.