erdekhayser
erdekhayser

Reputation: 6657

iOS 9 Content Filter replace occurrences of string

I am trying to make a content filter that censors webpages automatically by replacing the text of webpages with better alternatives ($'s and *'s in place of expletives, for example).

I found this pretty easy to do when creating an action extension, which lets you modify the webpage pretty easily. But for the actions in content filters, I'm not sure how to do this.

I figure that the code will need to look something like this:

[
    {
        "trigger": {
            "resource-type": ["script"]
        },
        "action": {
            "type": "css-display-none",
            "selector": "???"
        }
    }
]

"type": "css-display-none" seems like the only way for this to work, because the other types (block, block-cookies, and ignore-previous-rules) don't seem relevant here. However, I can't figure out how to replace text using CSS selectors.

I looked at this CSS selectors website that Apple referenced, but couldn't come up with a solution.

Edit

I am trying a different approach using Javascript instead of CSS, more like how the action extension works. I added the Javascript prototype to the Info.plist as the NSExtensionJavaScriptPreprocessingFile.

For some reason this code seems to do nothing. Why is the same code from the action extension not working in the content filter?

class ActionRequestHandler: NSObject, NSExtensionRequestHandling {

    var extensionContext: NSExtensionContext?

    func beginRequestWithExtensionContext(context: NSExtensionContext) {
        self.extensionContext = context

        for item: AnyObject in context.inputItems {

            let inputItem = item as! NSExtensionItem

            for provider: AnyObject in inputItem.attachments! {

                let itemProvider = provider as! NSItemProvider

                if itemProvider.hasItemConformingToTypeIdentifier(kUTTypePropertyList as String) {

                    itemProvider.loadItemForTypeIdentifier(kUTTypePropertyList as String, options: nil, completionHandler: { [unowned self] (result, error) in
                        if let dictionary = result as? NSDictionary {
                            self.itemLoadCompletedWithPreprocessingResults(dictionary[NSExtensionJavaScriptPreprocessingResultsKey] as! [NSObject: AnyObject])
                        }

                        })

                }
            }
        }
    }

    func itemLoadCompletedWithPreprocessingResults(javaScriptPreprocessingResults: [NSObject: AnyObject]) {
        let pageContent = javaScriptPreprocessingResults["content"] as! NSString
        let fixedContent = pageContent.stringByReplacingOccurrencesOfString("Bad Word", withString: "Good Word")
        self.doneWithResults(["content": fixedContent])
    }

    func doneWithResults(resultsForJavaScriptFinalizeArg: [NSObject: AnyObject]?) {
        if let resultsForJavaScriptFinalize = resultsForJavaScriptFinalizeArg {

            let resultsDictionary = [NSExtensionJavaScriptFinalizeArgumentKey: resultsForJavaScriptFinalize]

            let resultsProvider = NSItemProvider(item: resultsDictionary, typeIdentifier: String(kUTTypePropertyList))

            let resultsItem = NSExtensionItem()
            resultsItem.attachments = [resultsProvider]

            self.extensionContext!.completeRequestReturningItems([resultsItem], completionHandler: nil)
        } else {
            self.extensionContext!.completeRequestReturningItems([], completionHandler: nil)
        }

        self.extensionContext = nil
    }

}

Javascript action:

var Action = function() {};

Action.prototype = {

run: function(arguments) {
    arguments.completionFunction({"content": document.body.innerHTML});
},

finalize: function(arguments) {
    document.body.innerHTML = arguments["content"];
}

};

var ExtensionPreprocessingJS = new Action

Upvotes: 1

Views: 180

Answers (0)

Related Questions