<commit_before>/* This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. If a copy of the MPL was not distributed with this file, You can obtain one at http://mozilla.org/MPL/2.0/. */

// Based on  https://github.com/ninjinkun/NJKWebViewProgress
// MIT License https://github.com/ninjinkun/NJKWebViewProgress/blob/master/LICENSE

import Foundation

let completedUrlPath: String = "__completedprogress__"

public class WebViewProgress
{
    var loadingCount: Int = 0;
    var maxLoadCount: Int = 0;
    var interactive: Bool = false;

    let initialProgressValue: Double = 0.1;
    let interactiveProgressValue: Double = 0.5;
    let finalProgressValue: Double = 0.9;

    weak var webView: BraveWebView?;
    var currentURL: NSURL?;

    /* After all efforts to catch page load completion in WebViewProgress, sometimes, load completion is *still* missed.
    As a backup we can do KVO on 'loading'. Which can arrive too early (from subrequests) -and frequently- so delay checking by an arbitrary amount
    using a timer. The only problem with this is that there is yet more code for load detection, sigh.
    TODO figure this out. http://thestar.com exhibits this sometimes.
    Possibly a bug in UIWebView with load completion, but hard to repro, a reload of a page always seems to complete. */
    class LoadingObserver : NSObject {
        private weak var webView: BraveWebView?
        private var timer: NSTimer?

        let kvoLoading = "loading"

        init(webView:BraveWebView) {
            self.webView = webView
            super.init()
            webView.addObserver(self, forKeyPath: kvoLoading, options: .New, context: nil)
        }

        @objc func delayedCompletionCheck() {
            delay(0.01) { // ensure closure is on main thread
                if (self.webView?.loading ?? false) || self.webView?.estimatedProgress > 0.99 {
                    return
                }

                let readyState = self.webView?.stringByEvaluatingJavaScriptFromString("document.readyState")?.lowercaseString
                if readyState == "loaded" || readyState == "complete" {
                    self.webView?.progress.completeProgress()
                }
            }
        }

        @objc override func observeValueForKeyPath(keyPath: String?, ofObject object: AnyObject?, change: [String : AnyObject]?, context: UnsafeMutablePointer<Void>) {
            if let path = keyPath where path == "loading" {
                if !(webView?.loading ?? false) && webView?.estimatedProgress < 1.0 {
                    timer?.invalidate()
                    timer = NSTimer.scheduledTimerWithTimeInterval(0.5, target: self, selector: "delayedCompletionCheck", userInfo: nil, repeats: false)
                } else {
                    timer?.invalidate()
                }
            }
        }
    }
    var loadingObserver: LoadingObserver?

    init(parent: BraveWebView) {
        webView = parent
        currentURL = parent.request?.URL
        loadingObserver = LoadingObserver(webView: parent)
    }<commit_msg>Ensure that post-KVO operations are called on the main thread, as KVO is not guaranteed to be<commit_after>/* This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. If a copy of the MPL was not distributed with this file, You can obtain one at http://mozilla.org/MPL/2.0/. */

// Based on  https://github.com/ninjinkun/NJKWebViewProgress
// MIT License https://github.com/ninjinkun/NJKWebViewProgress/blob/master/LICENSE

import Foundation

let completedUrlPath: String = "__completedprogress__"

public class WebViewProgress
{
    var loadingCount: Int = 0;
    var maxLoadCount: Int = 0;
    var interactive: Bool = false;

    let initialProgressValue: Double = 0.1;
    let interactiveProgressValue: Double = 0.5;
    let finalProgressValue: Double = 0.9;

    weak var webView: BraveWebView?;
    var currentURL: NSURL?;

    /* After all efforts to catch page load completion in WebViewProgress, sometimes, load completion is *still* missed.
    As a backup we can do KVO on 'loading'. Which can arrive too early (from subrequests) -and frequently- so delay checking by an arbitrary amount
    using a timer. The only problem with this is that there is yet more code for load detection, sigh.
    TODO figure this out. http://thestar.com exhibits this sometimes.
    Possibly a bug in UIWebView with load completion, but hard to repro, a reload of a page always seems to complete. */
    class LoadingObserver : NSObject {
        private weak var webView: BraveWebView?
        private var timer: NSTimer?

        let kvoLoading = "loading"

        init(webView:BraveWebView) {
            self.webView = webView
            super.init()
            webView.addObserver(self, forKeyPath: kvoLoading, options: .New, context: nil)
        }

        @objc func delayedCompletionCheck() {
            if (webView?.loading ?? false) || webView?.estimatedProgress > 0.99 {
                return
            }

            let readyState = webView?.stringByEvaluatingJavaScriptFromString("document.readyState")?.lowercaseString
            if readyState == "loaded" || readyState == "complete" {
                webView?.progress.completeProgress()
            }
        }

        @objc override func observeValueForKeyPath(keyPath: String?, ofObject object: AnyObject?, change: [String : AnyObject]?, context: UnsafeMutablePointer<Void>) {
            guard let path = keyPath where path == "loading" else { return }
            delay(0) { // ensure closure is on main thread
                if !(self.webView?.loading ?? true) && self.webView?.estimatedProgress < 1.0 {
                    self.timer?.invalidate()
                    self.timer = NSTimer.scheduledTimerWithTimeInterval(0.5, target: self, selector: "delayedCompletionCheck", userInfo: nil, repeats: false)
                } else {
                    self.timer?.invalidate()
                }
            }
        }
    }
    var loadingObserver: LoadingObserver?

    init(parent: BraveWebView) {
        webView = parent
        currentURL = parent.request?.URL
        loadingObserver = LoadingObserver(webView: parent)
    }
{'fraction_non_alphanumeric': 0.08725048293625241, 'fraction_numerical': 0.006761107533805538, 'mean_word_length': 2.510169491525424, 'pattern_counts': {'":': 0, '<': 7, '<?xml version=': 0, '>': 7, 'https://': 4, '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': '2219448', 'n_tokens_mistral': 1703, 'n_tokens_neox': 1614, 'n_words': 560}