* Removed StringBuilder from Element.cssSelector
* Lint Code * Swift 4.1
This commit is contained in:
parent
306be6efbe
commit
d98300a7ec
12
CHANGELOG.md
12
CHANGELOG.md
|
@ -1,7 +1,17 @@
|
|||
# Change Log
|
||||
All notable changes to this project will be documented in this file.
|
||||
|
||||
## [1.6.3](https://github.com/scinfu/SwiftSoup/tree/1.6.4)
|
||||
## [1.6.6](https://github.com/scinfu/SwiftSoup/tree/1.6.6)
|
||||
* Removed StringBuilder from Element.cssSelector
|
||||
* Lint Code
|
||||
* Swift 4.1
|
||||
|
||||
## [1.6.5](https://github.com/scinfu/SwiftSoup/tree/1.6.5)
|
||||
* Removed StringBuilder from Element.cssSelector
|
||||
* Lint Code
|
||||
*
|
||||
|
||||
## [1.6.4](https://github.com/scinfu/SwiftSoup/tree/1.6.4)
|
||||
* Add newer simulators to targeted devices to build with Carthage [tvOS]
|
||||
|
||||
## [1.6.3](https://github.com/scinfu/SwiftSoup/tree/1.6.3)
|
||||
|
|
|
@ -13,7 +13,6 @@ class AppDelegate: UIResponder, UIApplicationDelegate {
|
|||
|
||||
var window: UIWindow?
|
||||
|
||||
|
||||
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
|
||||
// Override point for customization after application launch.
|
||||
return true
|
||||
|
@ -41,6 +40,4 @@ class AppDelegate: UIResponder, UIApplicationDelegate {
|
|||
// Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -15,10 +15,9 @@ class QueryViewControllerCell: UITableViewCell {
|
|||
|
||||
}
|
||||
|
||||
|
||||
class QueryViewController: UIViewController {
|
||||
|
||||
typealias Item = (selector: String,example: String, description: String)
|
||||
typealias Item = (selector: String, example: String, description: String)
|
||||
|
||||
//example items
|
||||
let items: [
|
||||
|
@ -36,35 +35,32 @@ class QueryViewController: UIViewController {
|
|||
Item(selector: "[attribute^=value]", example: "a[href^=https]", description: "Selects every <a> element whose href attribute value begins with \"https\""),
|
||||
Item(selector: "[attribute$=value]", example: "a[href$=.com/]", description: "Selects every <a> element whose href attribute value ends with \".com/\""),
|
||||
Item(selector: "[attribute*=value]", example: "a[href*=login]", description: "Selects every <a> element whose href attribute value contains the substring \"login\""),
|
||||
Item(selector: "[attr~=regex]", example: "img[src~=[gif]]", description: "elements with an attribute named \"img\", and value matching the regular expression"),
|
||||
Item(selector: "[attr~=regex]", example: "img[src~=[gif]]", description: "elements with an attribute named \"img\", and value matching the regular expression")
|
||||
]
|
||||
|
||||
var completionHandler: (Item)->Void = { arg in }
|
||||
var completionHandler: (Item) -> Void = { arg in }
|
||||
@IBOutlet weak var tableView: UITableView!
|
||||
|
||||
|
||||
override func viewDidLoad() {
|
||||
super.viewDidLoad()
|
||||
self.title = ""
|
||||
|
||||
self.tableView.rowHeight = UITableViewAutomaticDimension;
|
||||
self.tableView.estimatedRowHeight = UITableViewAutomaticDimension;
|
||||
self.tableView.rowHeight = UITableViewAutomaticDimension
|
||||
self.tableView.estimatedRowHeight = UITableViewAutomaticDimension
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
extension QueryViewController: UITableViewDataSource
|
||||
{
|
||||
extension QueryViewController: UITableViewDataSource {
|
||||
func numberOfSections(in tableView: UITableView) -> Int {
|
||||
return 1
|
||||
}
|
||||
|
||||
public func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int{
|
||||
public func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
|
||||
return items.count
|
||||
}
|
||||
|
||||
|
||||
public func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell{
|
||||
public func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
|
||||
let cell = tableView.dequeueReusableCell(withIdentifier: "QueryViewControllerCell", for: indexPath) as! QueryViewControllerCell
|
||||
|
||||
cell.selector.text = items[indexPath.row].selector
|
||||
|
@ -79,8 +75,7 @@ extension QueryViewController: UITableViewDataSource
|
|||
}
|
||||
}
|
||||
|
||||
extension QueryViewController: UITableViewDelegate
|
||||
{
|
||||
extension QueryViewController: UITableViewDelegate {
|
||||
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
|
||||
// user select an item
|
||||
completionHandler(items[indexPath.row])
|
||||
|
|
|
@ -27,8 +27,8 @@ class ViewController: UIViewController {
|
|||
|
||||
self.title = "SwiftSoup Example"
|
||||
|
||||
self.tableView.rowHeight = UITableViewAutomaticDimension;
|
||||
self.tableView.estimatedRowHeight = UITableViewAutomaticDimension;
|
||||
self.tableView.rowHeight = UITableViewAutomaticDimension
|
||||
self.tableView.estimatedRowHeight = UITableViewAutomaticDimension
|
||||
|
||||
urlTextField.text = "http://www.facebook.com"
|
||||
cssTextField.text = "div"
|
||||
|
@ -37,9 +37,8 @@ class ViewController: UIViewController {
|
|||
downloadHTML()
|
||||
}
|
||||
|
||||
|
||||
//Download HTML
|
||||
func downloadHTML(){
|
||||
func downloadHTML() {
|
||||
// url string to URL
|
||||
guard let url = URL(string: urlTextField.text ?? "") else {
|
||||
// an error occurred
|
||||
|
@ -62,14 +61,14 @@ class ViewController: UIViewController {
|
|||
}
|
||||
|
||||
//Parse CSS selector
|
||||
func parse(){
|
||||
func parse() {
|
||||
do {
|
||||
//empty old items
|
||||
items = []
|
||||
// firn css selector
|
||||
let elements: Elements = try document.select(cssTextField.text ?? "")
|
||||
//transform it into a local object (Item)
|
||||
for element in elements{
|
||||
for element in elements {
|
||||
let text = try element.text()
|
||||
let html = try element.outerHtml()
|
||||
items.append(Item(text: text, html: html))
|
||||
|
@ -83,7 +82,7 @@ class ViewController: UIViewController {
|
|||
}
|
||||
|
||||
@IBAction func chooseQuery(_ sender: Any) {
|
||||
guard let vc = storyboard?.instantiateViewController(withIdentifier: "QueryViewController") as? QueryViewController else{
|
||||
guard let vc = storyboard?.instantiateViewController(withIdentifier: "QueryViewController") as? QueryViewController else {
|
||||
return
|
||||
}
|
||||
vc.completionHandler = {[weak self](resilt) in
|
||||
|
@ -94,25 +93,21 @@ class ViewController: UIViewController {
|
|||
self.show(vc, sender: self)
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
extension ViewController: UITableViewDataSource
|
||||
{
|
||||
extension ViewController: UITableViewDataSource {
|
||||
func numberOfSections(in tableView: UITableView) -> Int {
|
||||
return 1
|
||||
}
|
||||
|
||||
public func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int{
|
||||
public func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
|
||||
return items.count
|
||||
}
|
||||
|
||||
|
||||
public func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell{
|
||||
public func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
|
||||
var cell = tableView.dequeueReusableCell(withIdentifier: "cell")
|
||||
if cell == nil {
|
||||
cell = UITableViewCell.init(style: UITableViewCellStyle.subtitle , reuseIdentifier: "cell")
|
||||
cell = UITableViewCell.init(style: UITableViewCellStyle.subtitle, reuseIdentifier: "cell")
|
||||
cell?.textLabel?.numberOfLines = 2
|
||||
cell?.detailTextLabel?.numberOfLines = 6
|
||||
|
||||
|
@ -129,19 +124,15 @@ extension ViewController: UITableViewDataSource
|
|||
let color2 = UIColor.init(red: 240.0/255, green: 240.0/255, blue: 240.0/255, alpha: 1)
|
||||
cell?.backgroundColor = (indexPath.row % 2) == 0 ? color1 : color2
|
||||
|
||||
|
||||
|
||||
return cell!
|
||||
}
|
||||
}
|
||||
|
||||
extension ViewController: UITableViewDelegate
|
||||
{
|
||||
extension ViewController: UITableViewDelegate {
|
||||
}
|
||||
|
||||
extension ViewController: UITextFieldDelegate
|
||||
{
|
||||
public func textFieldShouldReturn(_ textField: UITextField) -> Bool{
|
||||
extension ViewController: UITextFieldDelegate {
|
||||
public func textFieldShouldReturn(_ textField: UITextField) -> Bool {
|
||||
textField.resignFirstResponder()
|
||||
return false
|
||||
}
|
||||
|
@ -158,13 +149,10 @@ extension ViewController: UITextFieldDelegate
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
extension UIAlertController {
|
||||
static public func showAlert(_ message: String, _ controller: UIViewController){
|
||||
static public func showAlert(_ message: String, _ controller: UIViewController) {
|
||||
let alert = UIAlertController(title: "Alert", message: message, preferredStyle: UIAlertControllerStyle.alert)
|
||||
alert.addAction(UIAlertAction(title: "OK", style: UIAlertActionStyle.default, handler: nil))
|
||||
controller.present(alert, animated: true, completion: nil)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -5,10 +5,10 @@ import PackageDescription
|
|||
let package = Package(
|
||||
name: "SwiftSoup",
|
||||
products: [
|
||||
.library(name: "SwiftSoup", targets: ["SwiftSoup"]),
|
||||
.library(name: "SwiftSoup", targets: ["SwiftSoup"])
|
||||
],
|
||||
targets: [
|
||||
.target(name: "SwiftSoup", path: "Sources"),
|
||||
.testTarget(name: "SwiftSoupTests", dependencies: ["SwiftSoup"]),
|
||||
.testTarget(name: "SwiftSoupTests", dependencies: ["SwiftSoup"])
|
||||
]
|
||||
)
|
||||
|
|
|
@ -140,7 +140,7 @@ open class Attribute {
|
|||
}
|
||||
}
|
||||
|
||||
extension Attribute : Equatable {
|
||||
extension Attribute: Equatable {
|
||||
static public func == (lhs: Attribute, rhs: Attribute) -> Bool {
|
||||
return lhs.value == rhs.value && lhs.key == rhs.key
|
||||
}
|
||||
|
|
|
@ -38,7 +38,7 @@ open class Attributes: NSCopying {
|
|||
@see #hasKey(String)
|
||||
*/
|
||||
open func get(key: String) -> String {
|
||||
let attr: Attribute? = attributes.get(key:key)
|
||||
let attr: Attribute? = attributes.get(key: key)
|
||||
return attr != nil ? attr!.getValue() : ""
|
||||
}
|
||||
|
||||
|
@ -86,7 +86,7 @@ open class Attributes: NSCopying {
|
|||
@param attribute attribute
|
||||
*/
|
||||
open func put(attribute: Attribute) {
|
||||
attributes.put(value: attribute, forKey:attribute.getKey())
|
||||
attributes.put(value: attribute, forKey: attribute.getKey())
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -254,7 +254,7 @@ open class Attributes: NSCopying {
|
|||
|
||||
}
|
||||
|
||||
extension Attributes : Sequence {
|
||||
extension Attributes: Sequence {
|
||||
public func makeIterator() -> AnyIterator<Attribute> {
|
||||
var list = attributes.orderedValues
|
||||
return AnyIterator {
|
||||
|
|
|
@ -24,7 +24,7 @@ extension Character {
|
|||
|
||||
var isWhitespace: Bool {
|
||||
switch self {
|
||||
case Character.space, Character.BackslashT, Character.BackslashN,Character.BackslashF,Character.BackslashR: return true
|
||||
case Character.space, Character.BackslashT, Character.BackslashN, Character.BackslashF, Character.BackslashR: return true
|
||||
case Character.BackshashRBackslashN: return true
|
||||
default: return false
|
||||
|
||||
|
|
|
@ -118,7 +118,7 @@ extension Cleaner {
|
|||
//let sourceData: DataNode = (DataNode) source
|
||||
let destData: DataNode = DataNode(sourceData.getWholeData(), source.getBaseUri())
|
||||
try destination?.appendChild(destData)
|
||||
}else{
|
||||
} else {
|
||||
numDiscarded+=1
|
||||
}
|
||||
} else { // else, we don't care about comments, xml proc instructions, etc
|
||||
|
|
|
@ -13,7 +13,7 @@ import Foundation
|
|||
*/
|
||||
public class DocumentType: Node {
|
||||
static let PUBLIC_KEY: String = "PUBLIC"
|
||||
static let SYSTEM_KEY: String = "SYSTEM";
|
||||
static let SYSTEM_KEY: String = "SYSTEM"
|
||||
private static let NAME: String = "name"
|
||||
private static let PUB_SYS_KEY: String = "pubSysKey"; // PUBLIC or SYSTEM
|
||||
private static let PUBLIC_ID: String = "publicId"
|
||||
|
@ -30,12 +30,12 @@ public class DocumentType: Node {
|
|||
public init(_ name: String, _ publicId: String, _ systemId: String, _ baseUri: String) {
|
||||
super.init(baseUri)
|
||||
do {
|
||||
try attr(DocumentType.NAME, name);
|
||||
try attr(DocumentType.PUBLIC_ID, publicId);
|
||||
try attr(DocumentType.NAME, name)
|
||||
try attr(DocumentType.PUBLIC_ID, publicId)
|
||||
if (has(DocumentType.PUBLIC_ID)) {
|
||||
try attr(DocumentType.PUB_SYS_KEY, DocumentType.PUBLIC_KEY);
|
||||
try attr(DocumentType.PUB_SYS_KEY, DocumentType.PUBLIC_KEY)
|
||||
}
|
||||
try attr(DocumentType.SYSTEM_ID, systemId);
|
||||
try attr(DocumentType.SYSTEM_ID, systemId)
|
||||
} catch {}
|
||||
}
|
||||
|
||||
|
@ -50,18 +50,14 @@ public class DocumentType: Node {
|
|||
super.init(baseUri)
|
||||
do {
|
||||
try attr(DocumentType.NAME, name)
|
||||
if(pubSysKey != nil){
|
||||
if(pubSysKey != nil) {
|
||||
try attr(DocumentType.PUB_SYS_KEY, pubSysKey!)
|
||||
}
|
||||
try attr(DocumentType.PUBLIC_ID, publicId);
|
||||
try attr(DocumentType.SYSTEM_ID, systemId);
|
||||
try attr(DocumentType.PUBLIC_ID, publicId)
|
||||
try attr(DocumentType.SYSTEM_ID, systemId)
|
||||
} catch {}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
public override func nodeName() -> String {
|
||||
return "#doctype"
|
||||
}
|
||||
|
@ -80,7 +76,7 @@ public class DocumentType: Node {
|
|||
|
||||
}
|
||||
|
||||
if (has(DocumentType.PUB_SYS_KEY)){
|
||||
if (has(DocumentType.PUB_SYS_KEY)) {
|
||||
do {
|
||||
try accum.append(" ").append(attr(DocumentType.PUB_SYS_KEY))
|
||||
} catch {}
|
||||
|
@ -88,7 +84,7 @@ public class DocumentType: Node {
|
|||
|
||||
if (has(DocumentType.PUBLIC_ID)) {
|
||||
do {
|
||||
try accum.append(" \"").append(attr(DocumentType.PUBLIC_ID)).append("\"");
|
||||
try accum.append(" \"").append(attr(DocumentType.PUBLIC_ID)).append("\"")
|
||||
} catch {}
|
||||
|
||||
}
|
||||
|
|
|
@ -283,7 +283,7 @@ open class Element: Node {
|
|||
* @return if this element matches the query
|
||||
*/
|
||||
public func iS(_ cssQuery: String)throws->Bool {
|
||||
return try iS(QueryParser.parse(cssQuery));
|
||||
return try iS(QueryParser.parse(cssQuery))
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -293,15 +293,11 @@ open class Element: Node {
|
|||
*/
|
||||
public func iS(_ evaluator: Evaluator)throws->Bool {
|
||||
guard let od = self.ownerDocument() else {
|
||||
return false;
|
||||
return false
|
||||
}
|
||||
return try evaluator.matches(od, self);
|
||||
return try evaluator.matches(od, self)
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Add a node child node to this element.
|
||||
*
|
||||
|
@ -1065,9 +1061,9 @@ open class Element: Node {
|
|||
* @return set of classnames, empty if no class attribute
|
||||
*/
|
||||
public func classNames()throws->OrderedSet<String> {
|
||||
let fitted = try className().replaceAll(of: Element.classSplit, with: " ", options:.caseInsensitive)
|
||||
let fitted = try className().replaceAll(of: Element.classSplit, with: " ", options: .caseInsensitive)
|
||||
let names: [String] = fitted.components(separatedBy: " ")
|
||||
let classNames: OrderedSet<String> = OrderedSet(sequence:names)
|
||||
let classNames: OrderedSet<String> = OrderedSet(sequence: names)
|
||||
classNames.remove(Element.emptyString) // if classNames() was empty, would include an empty class
|
||||
return classNames
|
||||
}
|
||||
|
|
|
@ -459,13 +459,13 @@ open class Elements: NSCopying {
|
|||
* @return true if at least one element in the list matches the query.
|
||||
*/
|
||||
open func iS(_ query: String)throws->Bool {
|
||||
let eval: Evaluator = try QueryParser.parse(query);
|
||||
let eval: Evaluator = try QueryParser.parse(query)
|
||||
for e: Element in this {
|
||||
if (try e.iS(eval)){
|
||||
return true;
|
||||
if (try e.iS(eval)) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false;
|
||||
return false
|
||||
|
||||
}
|
||||
|
||||
|
@ -600,7 +600,7 @@ public struct ElementsIterator: IteratorProtocol {
|
|||
/// Advances to the next element and returns it, or `nil` if no next element
|
||||
mutating public func next() -> Element? {
|
||||
let result = index < elements.size() ? elements.get(index) : nil
|
||||
index += 1;
|
||||
index += 1
|
||||
return result
|
||||
}
|
||||
}
|
||||
|
@ -614,6 +614,3 @@ extension Elements: Sequence {
|
|||
return ElementsIterator(self)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -21,11 +21,11 @@ public class Entities {
|
|||
public struct EscapeMode: Equatable {
|
||||
|
||||
/** Restricted entities suitable for XHTML output: lt, gt, amp, and quot only. */
|
||||
public static let xhtml: EscapeMode = EscapeMode(string:Entities.xhtml, size: 4, id: 0)
|
||||
public static let xhtml: EscapeMode = EscapeMode(string: Entities.xhtml, size: 4, id: 0)
|
||||
/** Default HTML output entities. */
|
||||
public static let base: EscapeMode = EscapeMode(string:Entities.base, size: 106, id: 1)
|
||||
public static let base: EscapeMode = EscapeMode(string: Entities.base, size: 106, id: 1)
|
||||
/** Complete HTML entities. */
|
||||
public static let extended: EscapeMode = EscapeMode(string:Entities.full, size: 2125, id: 2)
|
||||
public static let extended: EscapeMode = EscapeMode(string: Entities.full, size: 2125, id: 2)
|
||||
|
||||
fileprivate let value: Int
|
||||
|
||||
|
@ -45,7 +45,7 @@ public class Entities {
|
|||
return left.value != right.value
|
||||
}
|
||||
|
||||
private static let codeDelims : [UnicodeScalar] = [",", ";"]
|
||||
private static let codeDelims: [UnicodeScalar] = [",", ";"]
|
||||
|
||||
init(string: String, size: Int, id: Int) {
|
||||
nameKeys = [String](repeating: "", count: size)
|
||||
|
@ -54,35 +54,34 @@ public class Entities {
|
|||
nameVals = [String](repeating: "", count: size)
|
||||
value = id
|
||||
|
||||
|
||||
//Load()
|
||||
|
||||
var i = 0;
|
||||
var i = 0
|
||||
|
||||
let reader: CharacterReader = CharacterReader(string);
|
||||
let reader: CharacterReader = CharacterReader(string)
|
||||
|
||||
while (!reader.isEmpty()) {
|
||||
// NotNestedLessLess=10913,824;1887
|
||||
|
||||
let name: String = reader.consumeTo("=");
|
||||
reader.advance();
|
||||
let name: String = reader.consumeTo("=")
|
||||
reader.advance()
|
||||
let cp1: Int = Int(reader.consumeToAny(EscapeMode.codeDelims), radix: codepointRadix) ?? 0
|
||||
let codeDelim: UnicodeScalar = reader.current();
|
||||
reader.advance();
|
||||
let cp2: Int;
|
||||
let codeDelim: UnicodeScalar = reader.current()
|
||||
reader.advance()
|
||||
let cp2: Int
|
||||
if (codeDelim == ",") {
|
||||
cp2 = Int(reader.consumeTo(";"), radix: codepointRadix) ?? 0
|
||||
reader.advance();
|
||||
reader.advance()
|
||||
} else {
|
||||
cp2 = empty;
|
||||
cp2 = empty
|
||||
}
|
||||
let index: Int = Int(reader.consumeTo("\n"), radix: codepointRadix) ?? 0
|
||||
reader.advance();
|
||||
reader.advance()
|
||||
|
||||
nameKeys[i] = name;
|
||||
codeVals[i] = cp1;
|
||||
codeKeys[index] = cp1;
|
||||
nameVals[index] = name;
|
||||
nameKeys[i] = name
|
||||
codeVals[i] = cp1
|
||||
codeKeys[index] = cp1
|
||||
nameVals[index] = name
|
||||
|
||||
if (cp2 != empty) {
|
||||
var s = String()
|
||||
|
@ -94,8 +93,6 @@ public class Entities {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
// init(string: String, size: Int, id: Int) {
|
||||
// nameKeys = [String](repeating: "", count: size)
|
||||
// codeVals = [Int](repeating: 0, count: size)
|
||||
|
@ -199,7 +196,7 @@ public class Entities {
|
|||
* @deprecated does not support characters outside the BMP or multiple character names
|
||||
*/
|
||||
open static func getCharacterByName(name: String) -> Character {
|
||||
return Character.convertFromIntegerLiteral(value:EscapeMode.extended.codepointForName(name))
|
||||
return Character.convertFromIntegerLiteral(value: EscapeMode.extended.codepointForName(name))
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -233,7 +230,7 @@ public class Entities {
|
|||
return 0
|
||||
}
|
||||
|
||||
open static func escape(_ string: String, _ encode: String.Encoding = .utf8 )-> String{
|
||||
open static func escape(_ string: String, _ encode: String.Encoding = .utf8 ) -> String {
|
||||
return Entities.escape(string, OutputSettings().charset(encode).escapeMode(Entities.EscapeMode.extended))
|
||||
}
|
||||
|
||||
|
@ -333,7 +330,7 @@ public class Entities {
|
|||
if (name != emptyName) // ok for identity check
|
||||
{accum.append(UnicodeScalar.Ampersand).append(name).append(";")
|
||||
} else {
|
||||
accum.append("&#x").append(String.toHexString(n:Int(codePoint.value)) ).append(";")
|
||||
accum.append("&#x").append(String.toHexString(n: Int(codePoint.value)) ).append(";")
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -278,7 +278,7 @@ public class Evaluator {
|
|||
open override func matches(_ root: Element, _ element: Element)throws->Bool {
|
||||
if(element.hasAttr(key)) {
|
||||
let s = try element.attr(key)
|
||||
return pattern.matcher(in:s).find()
|
||||
return pattern.matcher(in: s).find()
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
|
|
@ -87,7 +87,7 @@ class HtmlTreeBuilder: TreeBuilder {
|
|||
}
|
||||
|
||||
root = try Element(Tag.valueOf("html", settings), baseUri)
|
||||
try Validate.notNull(obj:root)
|
||||
try Validate.notNull(obj: root)
|
||||
try doc.appendChild(root!)
|
||||
stack.append(root!)
|
||||
resetInsertionMode()
|
||||
|
@ -422,8 +422,8 @@ class HtmlTreeBuilder: TreeBuilder {
|
|||
private func replaceInQueue(_ queue: Array<Element?>, _ out: Element, _ input: Element)throws->Array<Element?> {
|
||||
var queue = queue
|
||||
var i: Int = -1
|
||||
for index in 0..<queue.count{
|
||||
if(out == queue[index]){
|
||||
for index in 0..<queue.count {
|
||||
if(out == queue[index]) {
|
||||
i = index
|
||||
}
|
||||
}
|
||||
|
|
|
@ -153,7 +153,7 @@ enum HtmlTreeBuilderState: String, HtmlTreeBuilderStateProtocol {
|
|||
// todo: charset switches
|
||||
} else if (name.equals("title")) {
|
||||
try HtmlTreeBuilderState.handleRcData(start, tb)
|
||||
} else if (StringUtil.inString(name, haystack:"noframes", "style")) {
|
||||
} else if (StringUtil.inString(name, haystack: "noframes", "style")) {
|
||||
try HtmlTreeBuilderState.handleRawtext(start, tb)
|
||||
} else if (name.equals("noscript")) {
|
||||
// else if noscript && scripting flag = true: rawtext (jsoup doesn't run script, to handle as noscript)
|
||||
|
@ -179,7 +179,7 @@ enum HtmlTreeBuilderState: String, HtmlTreeBuilderStateProtocol {
|
|||
if (name?.equals("head"))! {
|
||||
tb.pop()
|
||||
tb.transition(.AfterHead)
|
||||
} else if (name != nil && StringUtil.inString(name!, haystack:"body", "html", "br")) {
|
||||
} else if (name != nil && StringUtil.inString(name!, haystack: "body", "html", "br")) {
|
||||
return try anythingElse(t, tb)
|
||||
} else {
|
||||
tb.error(self)
|
||||
|
|
|
@ -560,7 +560,7 @@ open class Node: Equatable, Hashable {
|
|||
@return next sibling, or null if this is the last sibling
|
||||
*/
|
||||
open func nextSibling() -> Node? {
|
||||
guard let siblings: Array<Node> = parentNode?.childNodes else{
|
||||
guard let siblings: Array<Node> = parentNode?.childNodes else {
|
||||
return nil
|
||||
}
|
||||
|
||||
|
@ -708,7 +708,7 @@ open class Node: Equatable, Hashable {
|
|||
let currParent: Node = nodesToProcess.removeFirst()
|
||||
|
||||
for i in 0..<currParent.childNodes.count {
|
||||
let childClone: Node = currParent.childNodes[i].copy(parent:currParent)
|
||||
let childClone: Node = currParent.childNodes[i].copy(parent: currParent)
|
||||
currParent.childNodes[i] = childClone
|
||||
nodesToProcess.append(childClone)
|
||||
}
|
||||
|
@ -778,7 +778,7 @@ open class Node: Equatable, Hashable {
|
|||
|
||||
}
|
||||
|
||||
extension Node : CustomStringConvertible {
|
||||
extension Node: CustomStringConvertible {
|
||||
public var description: String {
|
||||
do {
|
||||
return try outerHtml()
|
||||
|
@ -789,7 +789,7 @@ extension Node : CustomStringConvertible {
|
|||
}
|
||||
}
|
||||
|
||||
extension Node : CustomDebugStringConvertible {
|
||||
extension Node: CustomDebugStringConvertible {
|
||||
private static let space = " "
|
||||
public var debugDescription: String {
|
||||
do {
|
||||
|
|
|
@ -74,7 +74,7 @@ public class OrderedDictionary<Key: Hashable, Value: Equatable>: MutableCollecti
|
|||
}
|
||||
|
||||
public var orderedValues: [Value] {
|
||||
return _orderedKeys.flatMap { _keysToValues[$0] }
|
||||
return _orderedKeys.compactMap { _keysToValues[$0] }
|
||||
}
|
||||
|
||||
// ======================================================= //
|
||||
|
@ -148,7 +148,7 @@ public class OrderedDictionary<Key: Hashable, Value: Equatable>: MutableCollecti
|
|||
|
||||
public func putAll(all: OrderedDictionary<Key, Value>) {
|
||||
for i in all.orderedKeys {
|
||||
put(value:all[i]!, forKey: i)
|
||||
put(value: all[i]!, forKey: i)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -170,7 +170,7 @@ public class OrderedDictionary<Key: Hashable, Value: Equatable>: MutableCollecti
|
|||
|
||||
@discardableResult
|
||||
public func remove(key: Key) -> Value? {
|
||||
return removeValueForKey(key:key)
|
||||
return removeValueForKey(key: key)
|
||||
}
|
||||
|
||||
public func removeAll(keepCapacity: Bool = true) {
|
||||
|
@ -391,8 +391,6 @@ extension OrderedDictionary: Equatable {
|
|||
// return lhs._orderedKeys == rhs._orderedKeys && lhs._keysToValues == rhs._keysToValues
|
||||
//}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Elements IteratorProtocol.
|
||||
*/
|
||||
|
@ -412,7 +410,7 @@ public struct OrderedDictionaryIterator<Key: Hashable, Value: Equatable>: Iterat
|
|||
mutating public func next() -> Value? {
|
||||
|
||||
let result = index < orderedDictionary.orderedKeys.count ? orderedDictionary[orderedDictionary.orderedKeys[index]] : nil
|
||||
index += 1;
|
||||
index += 1
|
||||
return result
|
||||
}
|
||||
}
|
||||
|
@ -422,13 +420,7 @@ public struct OrderedDictionaryIterator<Key: Hashable, Value: Equatable>: Iterat
|
|||
*/
|
||||
extension OrderedDictionary: Sequence {
|
||||
/// Returns an iterator over the elements of this sequence.
|
||||
func generate()->OrderedDictionaryIterator<Key, Value>
|
||||
{
|
||||
func generate()->OrderedDictionaryIterator<Key, Value> {
|
||||
return OrderedDictionaryIterator(self)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -107,7 +107,7 @@ public class OrderedSet<T: Hashable> {
|
|||
public func remove(_ object: T) {
|
||||
if let index = contents[object] {
|
||||
contents[object] = nil
|
||||
sequencedContents[index].deallocate(capacity: 1)
|
||||
sequencedContents[index].deallocate()
|
||||
sequencedContents.remove(at: index)
|
||||
|
||||
for (object, i) in contents {
|
||||
|
@ -151,7 +151,7 @@ public class OrderedSet<T: Hashable> {
|
|||
contents.removeAll()
|
||||
|
||||
for sequencedContent in sequencedContents {
|
||||
sequencedContent.deallocate(capacity: 1)
|
||||
sequencedContent.deallocate()
|
||||
}
|
||||
|
||||
sequencedContents.removeAll()
|
||||
|
|
|
@ -57,8 +57,3 @@ open class ParseSettings {
|
|||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -146,7 +146,7 @@ public class Parser {
|
|||
let nodeList: Array<Node> = try parseFragment(bodyHtml, body, baseUri)
|
||||
//var nodes: [Node] = nodeList.toArray(Node[nodeList.size()]) // the node list gets modified when re-parented
|
||||
if nodeList.count > 0 {
|
||||
for i in 1..<nodeList.count{
|
||||
for i in 1..<nodeList.count {
|
||||
try nodeList[i].remove()
|
||||
}
|
||||
}
|
||||
|
|
|
@ -24,14 +24,14 @@ public struct Pattern {
|
|||
}
|
||||
|
||||
func validate()throws {
|
||||
_ = try NSRegularExpression(pattern: self.pattern, options:[])
|
||||
_ = try NSRegularExpression(pattern: self.pattern, options: [])
|
||||
}
|
||||
|
||||
func matcher(in text: String) -> Matcher {
|
||||
do {
|
||||
let regex = try NSRegularExpression(pattern: self.pattern, options:[])
|
||||
let regex = try NSRegularExpression(pattern: self.pattern, options: [])
|
||||
let nsString = NSString(string: text)
|
||||
let results = regex.matches(in: text, options:[], range: NSRange(location: 0, length: nsString.length))
|
||||
let results = regex.matches(in: text, options: [], range: NSRange(location: 0, length: nsString.length))
|
||||
|
||||
return Matcher(results, text)
|
||||
} catch let error {
|
||||
|
|
|
@ -140,7 +140,7 @@ public class QueryParser {
|
|||
} else if (tq.matchChomp(".")) {
|
||||
try byClass()} else if (tq.matchesWord() || tq.matches("*|")) {try byTag()} else if (tq.matches("[")) {try byAttribute()} else if (tq.matchChomp("*")) { allElements()} else if (tq.matchChomp(":lt(")) {try indexLessThan()} else if (tq.matchChomp(":gt(")) {try indexGreaterThan()} else if (tq.matchChomp(":eq(")) {try indexEquals()} else if (tq.matches(":has(")) {try has()} else if (tq.matches(":contains(")) {try contains(false)} else if (tq.matches(":containsOwn(")) {try contains(true)} else if (tq.matches(":matches(")) {try matches(false)} else if (tq.matches(":matchesOwn(")) {try matches(true)} else if (tq.matches(":not(")) {try not()} else if (tq.matchChomp(":nth-child(")) {try cssNthChild(false, false)} else if (tq.matchChomp(":nth-last-child(")) {try cssNthChild(true, false)} else if (tq.matchChomp(":nth-of-type(")) {try cssNthChild(false, true)} else if (tq.matchChomp(":nth-last-of-type(")) {try cssNthChild(true, true)} else if (tq.matchChomp(":first-child")) {evals.append(Evaluator.IsFirstChild())} else if (tq.matchChomp(":last-child")) {evals.append(Evaluator.IsLastChild())} else if (tq.matchChomp(":first-of-type")) {evals.append(Evaluator.IsFirstOfType())} else if (tq.matchChomp(":last-of-type")) {evals.append(Evaluator.IsLastOfType())} else if (tq.matchChomp(":only-child")) {evals.append(Evaluator.IsOnlyChild())} else if (tq.matchChomp(":only-of-type")) {evals.append(Evaluator.IsOnlyOfType())} else if (tq.matchChomp(":empty")) {evals.append(Evaluator.IsEmpty())} else if (tq.matchChomp(":root")) {evals.append(Evaluator.IsRoot())} else // unhandled
|
||||
{
|
||||
throw Exception.Error(type: ExceptionType.SelectorParseException, Message:"Could not parse query \(query): unexpected token at \(tq.remainder())")
|
||||
throw Exception.Error(type: ExceptionType.SelectorParseException, Message: "Could not parse query \(query): unexpected token at \(tq.remainder())")
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -203,7 +203,7 @@ public class QueryParser {
|
|||
} else if (cq.matchChomp("~=")) {
|
||||
evals.append( Evaluator.AttributeWithValueMatching(key, Pattern.compile(cq.remainder())))
|
||||
} else {
|
||||
throw Exception.Error(type: ExceptionType.SelectorParseException, Message:"Could not parse attribute query '\(query)': unexpected token at '\(cq.remainder())'")
|
||||
throw Exception.Error(type: ExceptionType.SelectorParseException, Message: "Could not parse attribute query '\(query)': unexpected token at '\(cq.remainder())'")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -250,7 +250,7 @@ public class QueryParser {
|
|||
mB.find()
|
||||
b = Int(mB.group()!.replaceFirst(of: "^\\+", with: ""))!
|
||||
} else {
|
||||
throw Exception.Error(type: ExceptionType.SelectorParseException, Message:"Could not parse nth-index '\(argS)': unexpected format")
|
||||
throw Exception.Error(type: ExceptionType.SelectorParseException, Message: "Could not parse nth-index '\(argS)': unexpected format")
|
||||
}
|
||||
if (ofType) {
|
||||
if (backwards) {
|
||||
|
|
|
@ -67,20 +67,20 @@ class StreamReader {
|
|||
}
|
||||
|
||||
/// Start reading from the beginning of file.
|
||||
func rewind() -> Void {
|
||||
func rewind() {
|
||||
fileHandle.seek(toFileOffset: 0)
|
||||
buffer.count = 0
|
||||
atEof = false
|
||||
}
|
||||
|
||||
/// Close the underlying file. No reading must be done after calling this method.
|
||||
func close() -> Void {
|
||||
func close() {
|
||||
fileHandle?.closeFile()
|
||||
fileHandle = nil
|
||||
}
|
||||
}
|
||||
|
||||
extension StreamReader : Sequence {
|
||||
extension StreamReader: Sequence {
|
||||
func makeIterator() -> AnyIterator<String> {
|
||||
return AnyIterator {
|
||||
return self.nextLine()
|
||||
|
|
|
@ -18,8 +18,7 @@ extension String {
|
|||
return String(self[i] as Character)
|
||||
}
|
||||
|
||||
init<S: Sequence>(_ ucs: S)where S.Iterator.Element == UnicodeScalar
|
||||
{
|
||||
init<S: Sequence>(_ ucs: S)where S.Iterator.Element == UnicodeScalar {
|
||||
var s = ""
|
||||
s.unicodeScalars.append(contentsOf: ucs)
|
||||
self = s
|
||||
|
@ -91,7 +90,7 @@ extension String {
|
|||
}
|
||||
|
||||
static func toHexString(n: Int) -> String {
|
||||
return String(format:"%2x", n)
|
||||
return String(format: "%2x", n)
|
||||
}
|
||||
|
||||
func insert(string: String, ind: Int) -> String {
|
||||
|
|
|
@ -127,7 +127,7 @@ open class StringBuilder {
|
|||
*/
|
||||
@discardableResult
|
||||
open func clear() -> StringBuilder {
|
||||
stringValue = Array();
|
||||
stringValue = Array()
|
||||
return self
|
||||
}
|
||||
}
|
||||
|
|
|
@ -215,7 +215,7 @@ open class StringUtil {
|
|||
if(base.pathComponents.count == 0 && base.absoluteString.last != "/" && !base.isFileURL) {
|
||||
base = base.appendingPathComponent("/", isDirectory: false)
|
||||
}
|
||||
let u = URL(string: relUrl, relativeTo : base)
|
||||
let u = URL(string: relUrl, relativeTo: base)
|
||||
return u
|
||||
}
|
||||
|
||||
|
|
|
@ -242,9 +242,9 @@ open class SwiftSoup {
|
|||
@see #clean(String, org.jsoup.safety.Whitelist)
|
||||
*/
|
||||
public static func isValid(_ bodyHtml: String, _ whitelist: Whitelist)throws->Bool {
|
||||
let dirty = try parseBodyFragment(bodyHtml, "");
|
||||
let cleaner = Cleaner(whitelist);
|
||||
return try cleaner.isValid(dirty);
|
||||
let dirty = try parseBodyFragment(bodyHtml, "")
|
||||
let cleaner = Cleaner(whitelist)
|
||||
return try cleaner.isValid(dirty)
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -215,7 +215,7 @@ open class Tag: Hashable {
|
|||
let this = lhs
|
||||
let o = rhs
|
||||
if (this === o) {return true}
|
||||
if (type(of:this) != type(of:o)) {return false}
|
||||
if (type(of: this) != type(of: o)) {return false}
|
||||
|
||||
let tag: Tag = o
|
||||
|
||||
|
|
|
@ -61,12 +61,10 @@ open class Token {
|
|||
return name.toString()
|
||||
}
|
||||
|
||||
func getPubSysKey()->String? {
|
||||
return pubSysKey;
|
||||
func getPubSysKey() -> String? {
|
||||
return pubSysKey
|
||||
}
|
||||
|
||||
|
||||
|
||||
func getPublicIdentifier() -> String {
|
||||
return publicIdentifier.toString()
|
||||
}
|
||||
|
@ -389,9 +387,9 @@ open class Token {
|
|||
|
||||
extension Token: CustomDebugStringConvertible {
|
||||
public var debugDescription: String {
|
||||
do{
|
||||
do {
|
||||
return try self.toString()
|
||||
}catch{
|
||||
} catch {
|
||||
return "Error while get string debug"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -18,7 +18,7 @@ final class Tokeniser {
|
|||
private var state: TokeniserState = TokeniserState.Data // current tokenisation state
|
||||
private var emitPending: Token? // the token we are about to emit on next read
|
||||
private var isEmitPending: Bool = false
|
||||
private var charsString: String? = nil // characters pending an emit. Will fall to charsBuilder if more than one
|
||||
private var charsString: String? // characters pending an emit. Will fall to charsBuilder if more than one
|
||||
private let charsBuilder: StringBuilder = StringBuilder(1024) // buffers characters to output as one token, if more than one emit per read
|
||||
let dataBuffer: StringBuilder = StringBuilder(1024) // buffers data looking for </script>
|
||||
|
||||
|
|
|
@ -620,7 +620,7 @@ enum TokeniserState: TokeniserStateProtocol {
|
|||
t.eofError(self)
|
||||
t.transition(.Data)
|
||||
break
|
||||
case "\"", "'",UnicodeScalar.LessThan, "=":
|
||||
case "\"", "'", UnicodeScalar.LessThan, "=":
|
||||
t.error(self)
|
||||
try t.tagPending.newAttribute()
|
||||
t.tagPending.appendAttributeName(c)
|
||||
|
@ -1185,7 +1185,7 @@ enum TokeniserState: TokeniserStateProtocol {
|
|||
t.doctypePending.pubSysKey = DocumentType.PUBLIC_KEY
|
||||
t.transition(.AfterDoctypePublicKeyword)
|
||||
} else if (r.matchConsumeIgnoreCase(DocumentType.SYSTEM_KEY)) {
|
||||
t.doctypePending.pubSysKey = DocumentType.SYSTEM_KEY;
|
||||
t.doctypePending.pubSysKey = DocumentType.SYSTEM_KEY
|
||||
t.transition(.AfterDoctypeSystemKeyword)
|
||||
} else {
|
||||
t.error(self)
|
||||
|
|
|
@ -16,9 +16,9 @@ private let symbolSet = CharacterSet.symbols
|
|||
private let digitSet = CharacterSet.decimalDigits
|
||||
|
||||
extension UnicodeScalar {
|
||||
public static let Ampersand : UnicodeScalar = "&"
|
||||
public static let LessThan : UnicodeScalar = "<"
|
||||
public static let GreaterThan : UnicodeScalar = ">"
|
||||
public static let Ampersand: UnicodeScalar = "&"
|
||||
public static let LessThan: UnicodeScalar = "<"
|
||||
public static let GreaterThan: UnicodeScalar = ">"
|
||||
|
||||
public static let Space: UnicodeScalar = " "
|
||||
public static let BackslashF: UnicodeScalar = UnicodeScalar(12)
|
||||
|
|
|
@ -14,7 +14,7 @@ struct Validate {
|
|||
* Validates that the object is not null
|
||||
* @param obj object to test
|
||||
*/
|
||||
public static func notNull(obj:Any?) throws {
|
||||
public static func notNull(obj: Any?) throws {
|
||||
if (obj == nil) {
|
||||
throw Exception.Error(type: ExceptionType.IllegalArgumentException, Message: "Object must not be null")
|
||||
}
|
||||
|
|
|
@ -209,7 +209,7 @@ public class Whitelist {
|
|||
*/
|
||||
@discardableResult
|
||||
open func removeTags(_ tags: String...)throws ->Whitelist {
|
||||
try Validate.notNull(obj:tags)
|
||||
try Validate.notNull(obj: tags)
|
||||
|
||||
for tag in tags {
|
||||
try Validate.notEmpty(string: tag)
|
||||
|
|
|
@ -366,6 +366,7 @@
|
|||
BD3B5BED1FC063BD001FDB3B /* InfotvOS.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; name = InfotvOS.plist; path = /Users/nabil/Documents/nabil/SwiftSoup/Sources/InfotvOS.plist; sourceTree = "<absolute>"; };
|
||||
BD3B5C2F1FC06423001FDB3B /* SwiftSoup.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = SwiftSoup.framework; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
BD3B5C301FC06424001FDB3B /* InfoWatchOS.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; name = InfoWatchOS.plist; path = /Users/nabil/Documents/nabil/SwiftSoup/Sources/InfoWatchOS.plist; sourceTree = "<absolute>"; };
|
||||
BD76883E206D8B6900B7F940 /* CHANGELOG.md */ = {isa = PBXFileReference; lastKnownFileType = net.daringfireball.markdown; path = CHANGELOG.md; sourceTree = "<group>"; };
|
||||
/* End PBXFileReference section */
|
||||
|
||||
/* Begin PBXFrameworksBuildPhase section */
|
||||
|
@ -522,6 +523,7 @@
|
|||
isa = PBXGroup;
|
||||
children = (
|
||||
BD36975B20135EBB00D8FAC6 /* SwiftSoup.podspec */,
|
||||
BD76883E206D8B6900B7F940 /* CHANGELOG.md */,
|
||||
8CE418181DAA54A900240B42 /* Sources */,
|
||||
8CE418231DAA54A900240B42 /* Tests */,
|
||||
8CE418171DAA54A900240B42 /* Products */,
|
||||
|
@ -667,6 +669,7 @@
|
|||
8CE418121DAA54A900240B42 /* Frameworks */,
|
||||
8CE418131DAA54A900240B42 /* Headers */,
|
||||
8CE418141DAA54A900240B42 /* Resources */,
|
||||
BD76883F206D9DAC00B7F940 /* ShellScript */,
|
||||
);
|
||||
buildRules = (
|
||||
);
|
||||
|
@ -756,7 +759,7 @@
|
|||
isa = PBXProject;
|
||||
attributes = {
|
||||
LastSwiftUpdateCheck = 0800;
|
||||
LastUpgradeCheck = 0900;
|
||||
LastUpgradeCheck = 0930;
|
||||
ORGANIZATIONNAME = "Nabil Chatbi";
|
||||
TargetAttributes = {
|
||||
8CE418151DAA54A900240B42 = {
|
||||
|
@ -836,6 +839,22 @@
|
|||
};
|
||||
/* End PBXResourcesBuildPhase section */
|
||||
|
||||
/* Begin PBXShellScriptBuildPhase section */
|
||||
BD76883F206D9DAC00B7F940 /* ShellScript */ = {
|
||||
isa = PBXShellScriptBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
);
|
||||
inputPaths = (
|
||||
);
|
||||
outputPaths = (
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
shellPath = /bin/sh;
|
||||
shellScript = "";
|
||||
};
|
||||
/* End PBXShellScriptBuildPhase section */
|
||||
|
||||
/* Begin PBXSourcesBuildPhase section */
|
||||
8CE418111DAA54A900240B42 /* Sources */ = {
|
||||
isa = PBXSourcesBuildPhase;
|
||||
|
@ -1144,6 +1163,7 @@
|
|||
CLANG_WARN_BOOL_CONVERSION = YES;
|
||||
CLANG_WARN_COMMA = YES;
|
||||
CLANG_WARN_CONSTANT_CONVERSION = YES;
|
||||
CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
|
||||
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
|
||||
CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
|
||||
CLANG_WARN_EMPTY_BODY = YES;
|
||||
|
@ -1151,6 +1171,7 @@
|
|||
CLANG_WARN_INFINITE_RECURSION = YES;
|
||||
CLANG_WARN_INT_CONVERSION = YES;
|
||||
CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
|
||||
CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
|
||||
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
|
||||
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
|
||||
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
|
||||
|
@ -1206,6 +1227,7 @@
|
|||
CLANG_WARN_BOOL_CONVERSION = YES;
|
||||
CLANG_WARN_COMMA = YES;
|
||||
CLANG_WARN_CONSTANT_CONVERSION = YES;
|
||||
CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
|
||||
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
|
||||
CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
|
||||
CLANG_WARN_EMPTY_BODY = YES;
|
||||
|
@ -1213,6 +1235,7 @@
|
|||
CLANG_WARN_INFINITE_RECURSION = YES;
|
||||
CLANG_WARN_INT_CONVERSION = YES;
|
||||
CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
|
||||
CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
|
||||
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
|
||||
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
|
||||
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
|
||||
|
|
|
@ -0,0 +1,8 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>IDEDidComputeMac32BitWarning</key>
|
||||
<true/>
|
||||
</dict>
|
||||
</plist>
|
|
@ -1,6 +1,6 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Scheme
|
||||
LastUpgradeVersion = "0900"
|
||||
LastUpgradeVersion = "0930"
|
||||
version = "1.3">
|
||||
<BuildAction
|
||||
parallelizeBuildables = "YES"
|
||||
|
@ -26,7 +26,6 @@
|
|||
buildConfiguration = "Debug"
|
||||
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
|
||||
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
|
||||
language = ""
|
||||
shouldUseLaunchSchemeArgsEnv = "YES">
|
||||
<Testables>
|
||||
<TestableReference
|
||||
|
@ -56,7 +55,6 @@
|
|||
buildConfiguration = "Debug"
|
||||
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
|
||||
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
|
||||
language = ""
|
||||
launchStyle = "0"
|
||||
useCustomWorkingDirectory = "NO"
|
||||
ignoresPersistentStateOnLaunch = "NO"
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Scheme
|
||||
LastUpgradeVersion = "0910"
|
||||
LastUpgradeVersion = "0930"
|
||||
version = "1.3">
|
||||
<BuildAction
|
||||
parallelizeBuildables = "YES"
|
||||
|
@ -26,7 +26,6 @@
|
|||
buildConfiguration = "Debug"
|
||||
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
|
||||
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
|
||||
language = ""
|
||||
shouldUseLaunchSchemeArgsEnv = "YES">
|
||||
<Testables>
|
||||
</Testables>
|
||||
|
@ -46,7 +45,6 @@
|
|||
buildConfiguration = "Debug"
|
||||
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
|
||||
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
|
||||
language = ""
|
||||
launchStyle = "0"
|
||||
useCustomWorkingDirectory = "NO"
|
||||
ignoresPersistentStateOnLaunch = "NO"
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Scheme
|
||||
LastUpgradeVersion = "0910"
|
||||
LastUpgradeVersion = "0930"
|
||||
version = "1.3">
|
||||
<BuildAction
|
||||
parallelizeBuildables = "YES"
|
||||
|
@ -26,7 +26,6 @@
|
|||
buildConfiguration = "Debug"
|
||||
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
|
||||
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
|
||||
language = ""
|
||||
shouldUseLaunchSchemeArgsEnv = "YES">
|
||||
<Testables>
|
||||
</Testables>
|
||||
|
@ -37,7 +36,6 @@
|
|||
buildConfiguration = "Debug"
|
||||
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
|
||||
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
|
||||
language = ""
|
||||
launchStyle = "0"
|
||||
useCustomWorkingDirectory = "NO"
|
||||
ignoresPersistentStateOnLaunch = "NO"
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Scheme
|
||||
LastUpgradeVersion = "0910"
|
||||
LastUpgradeVersion = "0930"
|
||||
version = "1.3">
|
||||
<BuildAction
|
||||
parallelizeBuildables = "YES"
|
||||
|
@ -26,7 +26,6 @@
|
|||
buildConfiguration = "Debug"
|
||||
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
|
||||
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
|
||||
language = ""
|
||||
shouldUseLaunchSchemeArgsEnv = "YES">
|
||||
<Testables>
|
||||
</Testables>
|
||||
|
@ -37,7 +36,6 @@
|
|||
buildConfiguration = "Debug"
|
||||
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
|
||||
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
|
||||
language = ""
|
||||
launchStyle = "0"
|
||||
useCustomWorkingDirectory = "NO"
|
||||
ignoresPersistentStateOnLaunch = "NO"
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Scheme
|
||||
LastUpgradeVersion = "0900"
|
||||
LastUpgradeVersion = "0930"
|
||||
version = "1.3">
|
||||
<BuildAction
|
||||
parallelizeBuildables = "YES"
|
||||
|
@ -26,7 +26,6 @@
|
|||
buildConfiguration = "Debug"
|
||||
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
|
||||
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
|
||||
language = ""
|
||||
shouldUseLaunchSchemeArgsEnv = "YES">
|
||||
<Testables>
|
||||
<TestableReference
|
||||
|
@ -56,7 +55,6 @@
|
|||
buildConfiguration = "Debug"
|
||||
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
|
||||
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
|
||||
language = ""
|
||||
launchStyle = "0"
|
||||
useCustomWorkingDirectory = "NO"
|
||||
ignoresPersistentStateOnLaunch = "NO"
|
||||
|
|
|
@ -31,5 +31,5 @@ XCTMain([
|
|||
testCase(NodeTest.allTests),
|
||||
testCase(AttributeTest.allTests),
|
||||
testCase(CleanerTest.allTests),
|
||||
testCase(StringUtilTest.allTests),
|
||||
testCase(StringUtilTest.allTests)
|
||||
])
|
||||
|
|
|
@ -115,7 +115,7 @@ class AttributeParseTest: XCTestCase {
|
|||
("teststrictAttributeUnescapes", teststrictAttributeUnescapes),
|
||||
("testmoreAttributeUnescapes", testmoreAttributeUnescapes),
|
||||
("testparsesBooleanAttributes", testparsesBooleanAttributes),
|
||||
("testdropsSlashFromAttributeName", testdropsSlashFromAttributeName),
|
||||
("testdropsSlashFromAttributeName", testdropsSlashFromAttributeName)
|
||||
]
|
||||
}()
|
||||
|
||||
|
|
|
@ -40,21 +40,20 @@ class AttributeTest: XCTestCase {
|
|||
try a.put("hello", "There")
|
||||
try a.put("data-name", "Jsoup")
|
||||
|
||||
XCTAssertEqual(5, a.size());
|
||||
try a.remove(key: "Tot");
|
||||
try a.remove(key: "Hello");
|
||||
XCTAssertEqual(3, a.size());
|
||||
XCTAssertTrue(a.hasKey(key: "tot"));
|
||||
XCTAssertFalse(a.hasKey(key: "Tot"));
|
||||
XCTAssertEqual(5, a.size())
|
||||
try a.remove(key: "Tot")
|
||||
try a.remove(key: "Hello")
|
||||
XCTAssertEqual(3, a.size())
|
||||
XCTAssertTrue(a.hasKey(key: "tot"))
|
||||
XCTAssertFalse(a.hasKey(key: "Tot"))
|
||||
}
|
||||
|
||||
|
||||
static var allTests = {
|
||||
return [
|
||||
("testLinuxTestSuiteIncludesAllTests", testLinuxTestSuiteIncludesAllTests),
|
||||
("testHtml", testHtml),
|
||||
("testWithSupplementaryCharacterInAttributeKeyAndValue", testWithSupplementaryCharacterInAttributeKeyAndValue),
|
||||
("testRemoveCaseSensitive",testRemoveCaseSensitive)
|
||||
("testRemoveCaseSensitive", testRemoveCaseSensitive)
|
||||
]
|
||||
}()
|
||||
|
||||
|
|
|
@ -20,7 +20,7 @@ class CleanerTest: XCTestCase {
|
|||
#endif
|
||||
}
|
||||
|
||||
func testHandlesCustomProtocols()throws{
|
||||
func testHandlesCustomProtocols()throws {
|
||||
let html = "<img src='cid:12345' /> <img src='data:gzzt' />"
|
||||
// let dropped = try SwiftSoup.clean(html, Whitelist.basicWithImages())
|
||||
// XCTAssertEqual("<img> \n<img>", dropped)
|
||||
|
@ -29,7 +29,6 @@ class CleanerTest: XCTestCase {
|
|||
XCTAssertEqual("<img src=\"cid:12345\"> \n<img src=\"data:gzzt\">", preserved)
|
||||
}
|
||||
|
||||
|
||||
func testSimpleBehaviourTest()throws {
|
||||
let h = "<div><p class=foo><a href='http://evil.com'>Hello <b id=bar>there</b>!</a></div>"
|
||||
let cleanHtml = try SwiftSoup.clean(h, Whitelist.simpleText())
|
||||
|
@ -70,14 +69,14 @@ class CleanerTest: XCTestCase {
|
|||
XCTAssertEqual("<p>Nice</p><blockquote>Hello</blockquote>", TextUtil.stripNewlines(cleanHtml!))
|
||||
}
|
||||
|
||||
func testRemoveAttributes()throws{
|
||||
func testRemoveAttributes()throws {
|
||||
let h = "<div><p>Nice</p><blockquote cite='http://example.com/quotations'>Hello</blockquote>"
|
||||
let cleanHtml = try SwiftSoup.clean(h, Whitelist.basic().removeAttributes("blockquote", "cite"))
|
||||
|
||||
XCTAssertEqual("<p>Nice</p><blockquote>Hello</blockquote>", TextUtil.stripNewlines(cleanHtml!))
|
||||
}
|
||||
|
||||
func testRemoveEnforcedAttributes()throws{
|
||||
func testRemoveEnforcedAttributes()throws {
|
||||
let h = "<div><p><A HREF='HTTP://nice.com'>Nice</a></p><blockquote>Hello</blockquote>"
|
||||
let cleanHtml = try SwiftSoup.clean(h, Whitelist.basic().removeEnforcedAttribute("a", "rel"))
|
||||
|
||||
|
@ -85,7 +84,7 @@ class CleanerTest: XCTestCase {
|
|||
TextUtil.stripNewlines(cleanHtml!))
|
||||
}
|
||||
|
||||
func testRemoveProtocols()throws{
|
||||
func testRemoveProtocols()throws {
|
||||
let h = "<p>Contact me <a href='mailto:info@example.com'>here</a></p>"
|
||||
let cleanHtml = try SwiftSoup.clean(h, Whitelist.basic().removeProtocols("a", "href", "ftp", "mailto"))
|
||||
|
||||
|
@ -93,37 +92,37 @@ class CleanerTest: XCTestCase {
|
|||
TextUtil.stripNewlines(cleanHtml!))
|
||||
}
|
||||
|
||||
func testDropComments()throws{
|
||||
func testDropComments()throws {
|
||||
let h = "<p>Hello<!-- no --></p>"
|
||||
let cleanHtml = try SwiftSoup.clean(h, Whitelist.relaxed())
|
||||
XCTAssertEqual("<p>Hello</p>", cleanHtml)
|
||||
}
|
||||
|
||||
func testDropXmlProc()throws{
|
||||
func testDropXmlProc()throws {
|
||||
let h = "<?import namespace=\"xss\"><p>Hello</p>"
|
||||
let cleanHtml = try SwiftSoup.clean(h, Whitelist.relaxed())
|
||||
XCTAssertEqual("<p>Hello</p>", cleanHtml)
|
||||
}
|
||||
|
||||
func testDropScript()throws{
|
||||
func testDropScript()throws {
|
||||
let h = "<SCRIPT SRC=//ha.ckers.org/.j><SCRIPT>alert(/XSS/.source)</SCRIPT>"
|
||||
let cleanHtml = try SwiftSoup.clean(h, Whitelist.relaxed())
|
||||
XCTAssertEqual("", cleanHtml)
|
||||
}
|
||||
|
||||
func testDropImageScript()throws{
|
||||
func testDropImageScript()throws {
|
||||
let h = "<IMG SRC=\"javascript:alert('XSS')\">"
|
||||
let cleanHtml = try SwiftSoup.clean(h, Whitelist.relaxed())
|
||||
XCTAssertEqual("<img>", cleanHtml)
|
||||
}
|
||||
|
||||
func testCleanJavascriptHref()throws{
|
||||
func testCleanJavascriptHref()throws {
|
||||
let h = "<A HREF=\"javascript:document.location='http://www.google.com/'\">XSS</A>"
|
||||
let cleanHtml = try SwiftSoup.clean(h, Whitelist.relaxed())
|
||||
XCTAssertEqual("<a>XSS</a>", cleanHtml)
|
||||
}
|
||||
|
||||
func testCleanAnchorProtocol()throws{
|
||||
func testCleanAnchorProtocol()throws {
|
||||
let validAnchor = "<a href=\"#valid\">Valid anchor</a>"
|
||||
let invalidAnchor = "<a href=\"#anchor with spaces\">Invalid anchor</a>"
|
||||
|
||||
|
@ -145,19 +144,19 @@ class CleanerTest: XCTestCase {
|
|||
XCTAssertEqual("<a>Invalid anchor</a>", cleanHtml)
|
||||
}
|
||||
|
||||
func testDropsUnknownTags()throws{
|
||||
func testDropsUnknownTags()throws {
|
||||
let h = "<p><custom foo=true>Test</custom></p>"
|
||||
let cleanHtml = try SwiftSoup.clean(h, Whitelist.relaxed())
|
||||
XCTAssertEqual("<p>Test</p>", cleanHtml)
|
||||
}
|
||||
|
||||
func testtestHandlesEmptyAttributes()throws{
|
||||
func testtestHandlesEmptyAttributes()throws {
|
||||
let h = "<img alt=\"\" src= unknown=''>"
|
||||
let cleanHtml = try SwiftSoup.clean(h, Whitelist.basicWithImages())
|
||||
XCTAssertEqual("<img alt=\"\">", cleanHtml)
|
||||
}
|
||||
|
||||
func testIsValid()throws{
|
||||
func testIsValid()throws {
|
||||
let ok = "<p>Test <b><a href='http://example.com/'>OK</a></b></p>"
|
||||
let nok1 = "<p><script></script>Not <b>OK</b></p>"
|
||||
let nok2 = "<p align=right>Test Not <b>OK</b></p>"
|
||||
|
@ -168,27 +167,25 @@ class CleanerTest: XCTestCase {
|
|||
XCTAssertFalse(try SwiftSoup.isValid(nok3, Whitelist.basic()))
|
||||
}
|
||||
|
||||
func testResolvesRelativeLinks()throws{
|
||||
func testResolvesRelativeLinks()throws {
|
||||
let html = "<a href='/foo'>Link</a><img src='/bar'>"
|
||||
let clean = try SwiftSoup.clean(html, "http://example.com/", Whitelist.basicWithImages())
|
||||
XCTAssertEqual("<a href=\"http://example.com/foo\" rel=\"nofollow\">Link</a>\n<img src=\"http://example.com/bar\">", clean)
|
||||
}
|
||||
|
||||
func testPreservesRelativeLinksIfConfigured()throws{
|
||||
func testPreservesRelativeLinksIfConfigured()throws {
|
||||
let html = "<a href='/foo'>Link</a><img src='/bar'> <img src='javascript:alert()'>"
|
||||
let clean = try SwiftSoup.clean(html, "http://example.com/", Whitelist.basicWithImages().preserveRelativeLinks(true))
|
||||
XCTAssertEqual("<a href=\"/foo\" rel=\"nofollow\">Link</a>\n<img src=\"/bar\"> \n<img>", clean)
|
||||
}
|
||||
|
||||
func testDropsUnresolvableRelativeLinks()throws{
|
||||
func testDropsUnresolvableRelativeLinks()throws {
|
||||
let html = "<a href='/foo'>Link</a>"
|
||||
let clean = try SwiftSoup.clean(html, Whitelist.basic())
|
||||
XCTAssertEqual("<a rel=\"nofollow\">Link</a>", clean)
|
||||
}
|
||||
|
||||
|
||||
|
||||
func testHandlesAllPseudoTag()throws{
|
||||
func testHandlesAllPseudoTag()throws {
|
||||
let html = "<p class='foo' src='bar'><a class='qux'>link</a></p>"
|
||||
let whitelist: Whitelist = try Whitelist()
|
||||
.addAttributes(":all", "class")
|
||||
|
@ -199,7 +196,7 @@ class CleanerTest: XCTestCase {
|
|||
XCTAssertEqual("<p class=\"foo\"><a class=\"qux\">link</a></p>", clean)
|
||||
}
|
||||
|
||||
func testAddsTagOnAttributesIfNotSet()throws{
|
||||
func testAddsTagOnAttributesIfNotSet()throws {
|
||||
let html = "<p class='foo' src='bar'>One</p>"
|
||||
let whitelist = try Whitelist()
|
||||
.addAttributes("p", "class")
|
||||
|
@ -231,7 +228,7 @@ class CleanerTest: XCTestCase {
|
|||
// XCTAssertEqual("<div><p>ℬ</p></div>", customOut2)
|
||||
// }
|
||||
|
||||
func testHandlesFramesets()throws{
|
||||
func testHandlesFramesets()throws {
|
||||
let dirty = "<html><head><script></script><noscript></noscript></head><frameset><frame src=\"foo\" /><frame src=\"foo\" /></frameset></html>"
|
||||
let clean = try SwiftSoup.clean(dirty, Whitelist.basic())
|
||||
XCTAssertEqual("", clean) // nothing good can come out of that
|
||||
|
@ -242,12 +239,11 @@ class CleanerTest: XCTestCase {
|
|||
XCTAssertEqual(0, cleanDoc?.body()?.childNodeSize())
|
||||
}
|
||||
|
||||
func testCleansInternationalText()throws{
|
||||
func testCleansInternationalText()throws {
|
||||
XCTAssertEqual("привет", try SwiftSoup.clean("привет", Whitelist.none()))
|
||||
}
|
||||
|
||||
|
||||
func testScriptTagInWhiteList()throws{
|
||||
func testScriptTagInWhiteList()throws {
|
||||
let whitelist: Whitelist = try Whitelist.relaxed()
|
||||
try whitelist.addTags( "script" )
|
||||
XCTAssertTrue( try SwiftSoup.isValid("Hello<script>alert('Doh')</script>World !", whitelist ) )
|
||||
|
@ -324,4 +320,3 @@ class CleanerTest: XCTestCase {
|
|||
}()
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -16,7 +16,7 @@ class CssTest: XCTestCase {
|
|||
override func setUp() {
|
||||
super.setUp()
|
||||
|
||||
let sb: StringBuilder = StringBuilder(string:"<html><head></head><body>")
|
||||
let sb: StringBuilder = StringBuilder(string: "<html><head></head><body>")
|
||||
|
||||
sb.append("<div id='pseudo'>")
|
||||
for i in 1...10 {
|
||||
|
|
|
@ -442,9 +442,7 @@ class DocumentTest: XCTestCase {
|
|||
return doc
|
||||
}
|
||||
|
||||
|
||||
func testThai()
|
||||
{
|
||||
func testThai() {
|
||||
let str = "บังคับ"
|
||||
guard let doc = try? SwiftSoup.parse(str) else {
|
||||
XCTFail()
|
||||
|
@ -478,7 +476,7 @@ class DocumentTest: XCTestCase {
|
|||
// output.contains(" ") || output.contains(" "));
|
||||
// }
|
||||
|
||||
func testNewLine(){
|
||||
func testNewLine() {
|
||||
let h = "<html><body><div>\r\n<div dir=\"ltr\">\r\n<div id=\"divtagdefaultwrapper\"><font face=\"Calibri,Helvetica,sans-serif\" size=\"3\" color=\"black\"><span style=\"font-size:12pt;\" id=\"divtagdefaultwrapper\">\r\n<div style=\"margin-top:0;margin-bottom:0;\"> TEST</div>\r\n<div style=\"margin-top:0;margin-bottom:0;\">TEST</div>\r\n<div style=\"margin-top:0;margin-bottom:0;\">TEST</div>\r\n<div style=\"margin-top:0;margin-bottom:0;\"><br>\r\n\r\n</div>\r\n<div style=\"margin-top:0;margin-bottom:0;\">TEST</div>\r\n<div style=\"margin-top:0;margin-bottom:0;\">TEST</div>\r\n<div style=\"margin-top:0;margin-bottom:0;\">TEST</div>\r\n<div style=\"margin-top:0;margin-bottom:0;\"><br>\r\n\r\n</div>\r\n<div style=\"margin-top:0;margin-bottom:0;\"><br>\r\n\r\n</div>\r\n<div style=\"margin-top:0;margin-bottom:0;\">TEST</div>\r\n<div style=\"margin-top:0;margin-bottom:0;\">TEST</div>\r\n<div style=\"margin-top:0;margin-bottom:0;\">TEST</div>\r\n<div style=\"margin-top:0;margin-bottom:0;\"><br>\r\n\r\n</div>\r\n<div style=\"margin-top:0;margin-bottom:0;\"><br>\r\n\r\n</div>\r\n<div style=\"margin-top:0;margin-bottom:0;\"><br>\r\n\r\n</div>\r\n<div style=\"margin-top:0;margin-bottom:0;\"><br>\r\n\r\n</div>\r\n<div style=\"margin-top:0;margin-bottom:0;\"><br>\r\n\r\n</div>\r\n<div style=\"margin-top:0;margin-bottom:0;\"><br>\r\n\r\n</div>\r\n<div style=\"margin-top:0;margin-bottom:0;\"><br>\r\n\r\n</div>\r\n<div style=\"margin-top:0;margin-bottom:0;\">TEST</div>\r\n</span></font></div>\r\n</div>\r\n</div>\r\n</body></html>"
|
||||
|
||||
let doc: Document = try! SwiftSoup.parse(h)
|
||||
|
@ -514,8 +512,8 @@ class DocumentTest: XCTestCase {
|
|||
("testMetaCharsetUpdateXmlDisabled", testMetaCharsetUpdateXmlDisabled),
|
||||
("testMetaCharsetUpdateXmlDisabledNoChanges", testMetaCharsetUpdateXmlDisabledNoChanges),
|
||||
("testMetaCharsetUpdatedDisabledPerDefault", testMetaCharsetUpdatedDisabledPerDefault),
|
||||
("testThai",testThai),
|
||||
("testNewLine", testNewLine),
|
||||
("testThai", testThai),
|
||||
("testNewLine", testNewLine)
|
||||
]
|
||||
}()
|
||||
|
||||
|
|
|
@ -55,7 +55,7 @@ class DocumentTypeTest: XCTestCase {
|
|||
("testConstructorValidationOkWithBlankName", testConstructorValidationOkWithBlankName),
|
||||
("testConstructorValidationThrowsExceptionOnNulls", testConstructorValidationThrowsExceptionOnNulls),
|
||||
("testConstructorValidationOkWithBlankPublicAndSystemIds", testConstructorValidationOkWithBlankPublicAndSystemIds),
|
||||
("testOuterHtmlGeneration", testOuterHtmlGeneration),
|
||||
("testOuterHtmlGeneration", testOuterHtmlGeneration)
|
||||
]
|
||||
}()
|
||||
}
|
||||
|
|
|
@ -823,7 +823,7 @@ class ElementTest: XCTestCase {
|
|||
|
||||
// Update the class names to a fresh set
|
||||
let newSet = OrderedSet<String>()
|
||||
newSet.append(contentsOf:set1)
|
||||
newSet.append(contentsOf: set1)
|
||||
//newSet["c3"] //todo: nabil not a set , add == append but not change exists c3
|
||||
|
||||
try div.classNames(newSet)
|
||||
|
@ -946,8 +946,8 @@ class ElementTest: XCTestCase {
|
|||
.removeAttr("two")
|
||||
.removeAttr("three")
|
||||
.removeAttr("four")
|
||||
.removeAttr("five");
|
||||
XCTAssertEqual("<a>Text</a>", try a.outerHtml());
|
||||
.removeAttr("five")
|
||||
XCTAssertEqual("<a>Text</a>", try a.outerHtml())
|
||||
}
|
||||
|
||||
func testIs()throws {
|
||||
|
@ -955,25 +955,23 @@ class ElementTest: XCTestCase {
|
|||
let doc: Document = try SwiftSoup.parse(html)
|
||||
let p: Element = try doc.select("p").first()!
|
||||
|
||||
try XCTAssertTrue(p.iS("p"));
|
||||
try XCTAssertFalse(p.iS("div"));
|
||||
try XCTAssertTrue(p.iS("p:has(a)"));
|
||||
try XCTAssertTrue(p.iS("p:first-child"));
|
||||
try XCTAssertFalse(p.iS("p:last-child"));
|
||||
try XCTAssertTrue(p.iS("*"));
|
||||
try XCTAssertTrue(p.iS("div p"));
|
||||
try XCTAssertTrue(p.iS("p"))
|
||||
try XCTAssertFalse(p.iS("div"))
|
||||
try XCTAssertTrue(p.iS("p:has(a)"))
|
||||
try XCTAssertTrue(p.iS("p:first-child"))
|
||||
try XCTAssertFalse(p.iS("p:last-child"))
|
||||
try XCTAssertTrue(p.iS("*"))
|
||||
try XCTAssertTrue(p.iS("div p"))
|
||||
|
||||
let q: Element = try doc.select("p").last()!
|
||||
try XCTAssertTrue(q.iS("p"));
|
||||
try XCTAssertTrue(q.iS("p ~ p"));
|
||||
try XCTAssertTrue(q.iS("p + p"));
|
||||
try XCTAssertTrue(q.iS("p:last-child"));
|
||||
try XCTAssertFalse(q.iS("p a"));
|
||||
try XCTAssertFalse(q.iS("a"));
|
||||
try XCTAssertTrue(q.iS("p"))
|
||||
try XCTAssertTrue(q.iS("p ~ p"))
|
||||
try XCTAssertTrue(q.iS("p + p"))
|
||||
try XCTAssertTrue(q.iS("p:last-child"))
|
||||
try XCTAssertFalse(q.iS("p a"))
|
||||
try XCTAssertFalse(q.iS("a"))
|
||||
}
|
||||
|
||||
|
||||
|
||||
static var allTests = {
|
||||
return [
|
||||
("testLinuxTestSuiteIncludesAllTests", testLinuxTestSuiteIncludesAllTests),
|
||||
|
@ -1046,8 +1044,8 @@ class ElementTest: XCTestCase {
|
|||
("testAppendMustCorrectlyMoveChildrenInsideOneParentElement", testAppendMustCorrectlyMoveChildrenInsideOneParentElement),
|
||||
("testHashcodeIsStableWithContentChanges", testHashcodeIsStableWithContentChanges),
|
||||
("testNamespacedElements", testNamespacedElements),
|
||||
("testChainedRemoveAttributes",testChainedRemoveAttributes),
|
||||
("testIs",testIs)
|
||||
("testChainedRemoveAttributes", testChainedRemoveAttributes),
|
||||
("testIs", testIs)
|
||||
]
|
||||
}()
|
||||
}
|
||||
|
|
|
@ -148,7 +148,6 @@ class EntitiesTest: XCTestCase {
|
|||
XCTAssertEqual("<a title=\"<p>One</p>\">One</a>", try element.outerHtml())
|
||||
}
|
||||
|
||||
|
||||
static var allTests = {
|
||||
return [
|
||||
("testLinuxTestSuiteIncludesAllTests", testLinuxTestSuiteIncludesAllTests),
|
||||
|
|
|
@ -124,15 +124,14 @@ class StringUtilTest: XCTestCase {
|
|||
return [
|
||||
("testLinuxTestSuiteIncludesAllTests", testLinuxTestSuiteIncludesAllTests),
|
||||
("testJoin", testJoin),
|
||||
("testPadding",testPadding),
|
||||
("testPadding", testPadding),
|
||||
("testIsBlank", testIsBlank),
|
||||
("testIsNumeric", testIsNumeric),
|
||||
("testIsWhitespace", testIsWhitespace),
|
||||
("testNormaliseWhiteSpace", testNormaliseWhiteSpace),
|
||||
("testNormaliseWhiteSpaceHandlesHighSurrogates", testNormaliseWhiteSpaceHandlesHighSurrogates),
|
||||
("testResolvesRelativeUrls", testResolvesRelativeUrls),
|
||||
("testResolvesRelativeUrls", testResolvesRelativeUrls)
|
||||
]
|
||||
}()
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -90,7 +90,7 @@ class TagTest: XCTestCase {
|
|||
("testPSemantics", testPSemantics),
|
||||
("testImgSemantics", testImgSemantics),
|
||||
("testDefaultSemantics", testDefaultSemantics),
|
||||
("testValueOfChecksNotEmpty", testValueOfChecksNotEmpty),
|
||||
("testValueOfChecksNotEmpty", testValueOfChecksNotEmpty)
|
||||
]
|
||||
}()
|
||||
}
|
||||
|
|
|
@ -187,7 +187,7 @@ class XmlTreeBuilderTest: XCTestCase {
|
|||
("testCreatesValidProlog", testCreatesValidProlog),
|
||||
("testPreservesCaseByDefault", testPreservesCaseByDefault),
|
||||
("testCanNormalizeCase", testCanNormalizeCase),
|
||||
("testNilReplaceInQueue",testNilReplaceInQueue)
|
||||
("testNilReplaceInQueue", testNilReplaceInQueue)
|
||||
]
|
||||
}()
|
||||
|
||||
|
|
Loading…
Reference in New Issue