<commit_before>//
//  FormattedTextField.swift
//  FormattedTextField
//
//  Created by <NAME> on 16/10/2016.
//
//

import UIKit

@objc public protocol FormattedTextFieldDelegate: UITextFieldDelegate {
    @objc optional func textField(_ textField: UITextField, shouldChangeUnformattedText text: String, in range: NSRange, replacementString: String) -> Bool
}

open class FormattedTextField: UITextField {
    open static let maskSymbol: Character = "×"

    public override init(frame: CGRect) {
        placeholderLabel = UILabel()

        super.init(frame: frame)
        commonInit()
    }

    public required init?(coder aDecoder: NSCoder) {
        placeholderLabel = UILabel()

        super.init(coder: aDecoder)
        commonInit()
    }

    private func commonInit() {
        delegateProxy.delegate = super.delegate
        super.delegate = delegateProxy

        if let unformattedText = unformattedText {
            var cursorPosition = 0
            text = formattedText(fromText: unformattedText, textMask: text, cursorPosition: &cursorPosition)
        }

        placeholderLabel.font = font
        placeholderLabel.textColor = UIColor(white: 170/255.0, alpha: 0.5)
        if let attributedPlaceholder = super.attributedPlaceholder {
            placeholderLabel.attributedText = attributedPlaceholder
        } else if let placeholder = super.placeholder {
            placeholderLabel.text = placeholder
        }
        addSubview(placeholderLabel)
    }

    @IBInspectable open var textMask: String? {
        didSet(oldMask) {
            var cursorPosition: Int = 0

            let unformattedText = unformatterText(fromText: (text ?? ""), textMask: oldMask, cursorPosition: &cursorPosition)
            let newFormattedText = formattedText(fromText: unformattedText, textMask: textMask, cursorPosition: &cursorPosition)
            text = newFormattedText
        }
    }

    @IBInspectable open var unformattedText: String? {
        get {
            guard let text = text else {
                return nil
            }
            var cursorPosition = 0
            let unformattedText = self.unformatterText(fromText: text, textMask: textMask, cursorPosition: &cursorPosition)

            return unformattedText
        }
        set(value) {
            var cursorPosition = 0
            let unformattedText = value ?? ""
            let formattedText = self.formattedText(fromText: unformattedText, textMask: textMask, cursorPosition: &cursorPosition)
            if formattedText.characters.count > 0 || value != nil {
                text = formattedText
            } else {
                text = nil
            }<commit_msg>Add restoration text selection after changing mask<commit_after>//
//  FormattedTextField.swift
//  FormattedTextField
//
//  Created by <NAME> on 16/10/2016.
//
//

import UIKit

@objc public protocol FormattedTextFieldDelegate: UITextFieldDelegate {
    @objc optional func textField(_ textField: UITextField, shouldChangeUnformattedText text: String, in range: NSRange, replacementString: String) -> Bool
}

open class FormattedTextField: UITextField {
    open static let maskSymbol: Character = "×"

    public override init(frame: CGRect) {
        placeholderLabel = UILabel()

        super.init(frame: frame)
        commonInit()
    }

    public required init?(coder aDecoder: NSCoder) {
        placeholderLabel = UILabel()

        super.init(coder: aDecoder)
        commonInit()
    }

    private func commonInit() {
        delegateProxy.delegate = super.delegate
        super.delegate = delegateProxy

        if let unformattedText = unformattedText {
            var cursorPosition = 0
            text = formattedText(fromText: unformattedText, textMask: text, cursorPosition: &cursorPosition)
        }

        placeholderLabel.font = font
        placeholderLabel.textColor = UIColor(white: 170/255.0, alpha: 0.5)
        if let attributedPlaceholder = super.attributedPlaceholder {
            placeholderLabel.attributedText = attributedPlaceholder
        } else if let placeholder = super.placeholder {
            placeholderLabel.text = placeholder
        }
        addSubview(placeholderLabel)
    }

    @IBInspectable open var textMask: String? {
        didSet(oldMask) {
            var cursorPosition: Int = 0
            if let selectedRange = selectedCharachtersRange, let text = text {
                cursorPosition = text.distance(from: text.startIndex, to: selectedRange.lowerBound)
            } else {
                cursorPosition = 0
            }

            let unformattedText = unformatterText(fromText: (text ?? ""), textMask: oldMask, cursorPosition: &cursorPosition)
            let newFormattedText = formattedText(fromText: unformattedText, textMask: textMask, cursorPosition: &cursorPosition)
            text = newFormattedText

            if selectedTextRange != nil {
                let cursorIndex = newFormattedText.index(newFormattedText.startIndex, offsetBy: cursorPosition, limitedBy: newFormattedText.endIndex) ?? newFormattedText.endIndex
                selectedCharachtersRange = cursorIndex..<cursorIndex
            }
        }
    }

    @IBInspectable open var unformattedText: String? {
        get {
            guard let text = text else {
                return nil
            }
            var cursorPosition = 0
            let unformattedText = self.unformatterText(fromText: text, textMask: textMask, cursorPosition: &cursorPosition)

            return unformattedText
        }
        set(value) {
            var cursorPosition = 0
            let unformattedText = value ?? ""
            let formattedText = self.formattedText(fromText: unformattedText, textMask: textMask, cursorPosition: &cursorPosition)
            if formattedText.characters.count > 0 || value != nil {
                text = formattedText
            } else {
                text = nil
            }
{'fraction_non_alphanumeric': 0.0774280424171015, 'fraction_numerical': 0.007574482410368625, 'mean_word_length': 2.3703913783323878, 'pattern_counts': {'":': 0, '<': 6, '<?xml version=': 0, '>': 9, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1679351', 'n_tokens_mistral': 1595, 'n_tokens_neox': 1499, 'n_words': 394}