~abreu-alexandre/webbrowser-app/add-scheme-filter-handler

« back to all changes in this revision

Viewing changes to src/app/webbrowser/Suggestions.qml

  • Committer: CI Train Bot
  • Author(s): Olivier Tilloy
  • Date: 2015-08-11 11:18:43 UTC
  • mfrom: (1115.1.5 highlightTerms-in-one-pass)
  • Revision ID: ci-train-bot@canonical.com-20150811111843-k6nferv7frcqxa2z
Highlight matching terms in one pass. Fixes: #1481206
Approved by: PS Jenkins bot, Ugo Riboni

Show diffs side-by-side

added added

removed removed

Lines of Context:
25
25
    property var searchTerms
26
26
    property var models
27
27
 
28
 
    readonly property int count: models.reduce(countItems, 0)
 
28
    readonly property int count: models.reduce(internal.countItems, 0)
29
29
    readonly property alias contentHeight: suggestionsList.contentHeight
30
30
 
31
31
    signal activated(url url)
43
43
 
44
44
    ListView {
45
45
        id: suggestionsList
 
46
        objectName: "suggestionsList"
46
47
        anchors.fill: parent
47
48
        focus: true
48
49
 
49
50
        model: models.reduce(function(list, model) {
50
 
            var modelItems = [];
 
51
            var modelItems = []
51
52
 
52
53
            // Models inheriting from QAbstractItemModel and JS arrays expose their
53
54
            // data differently, so we need to collect their items differently
60
61
            modelItems.forEach(function(item) {
61
62
                item["icon"] = model.icon
62
63
                item["displayUrl"] = model.displayUrl
63
 
                list.push(item);
 
64
                list.push(item)
64
65
            })
65
 
            return list;
 
66
            return list
66
67
        }, [])
67
68
 
68
69
        delegate: Suggestion {
 
70
            objectName: "suggestionDelegate_" + index
69
71
            width: suggestionsList.width
70
72
            showDivider: index < model.length - 1
71
73
 
72
 
            title: selected ? modelData.title : highlightTerms(modelData.title)
73
 
            subtitle: modelData.displayUrl ? (selected ? modelData.url : highlightTerms(modelData.url)) : ""
 
74
            title: selected ? modelData.title : internal.highlightTerms(modelData.title)
 
75
            subtitle: modelData.displayUrl ? (selected ? modelData.url : internal.highlightTerms(modelData.url)) : ""
74
76
            icon: modelData.icon
75
77
            selected: suggestionsList.activeFocus && ListView.isCurrentItem
76
78
 
83
85
        align: Qt.AlignTrailing
84
86
    }
85
87
 
86
 
    function escapeTerm(term) {
87
 
        // Build a regular expression suitable for highlighting a term
88
 
        // in a case-insensitive manner and globally, by escaping
89
 
        // special characters (a simpler version of preg_quote).
90
 
        var escaped = term.replace(/[().?]/g, '\\$&')
91
 
        return new RegExp(escaped, 'ig')
92
 
    }
93
 
 
94
 
    function highlightTerms(text) {
95
 
        // Highlight the matching terms (bold and Ubuntu orange)
96
 
        if (text === undefined) {
97
 
            return ''
98
 
        }
99
 
        var highlighted = text.toString()
100
 
        var count = searchTerms.length
101
 
        var highlight = '<font color="%1">$&</font>'.arg("#752571")
102
 
        for (var i = 0; i < count; ++i) {
103
 
            var term = searchTerms[i]
104
 
            highlighted = highlighted.replace(escapeTerm(term), highlight)
105
 
        }
106
 
        highlighted = highlighted.replace(new RegExp('&', 'g'), '&amp;')
107
 
        highlighted = '<html>' + highlighted + '</html>'
108
 
        return highlighted
109
 
    }
110
 
 
111
 
    function countItems(total, model) {
112
 
        return total + (model.hasOwnProperty("length") ? model.length : model.count);
 
88
    QtObject {
 
89
        id: internal
 
90
 
 
91
        readonly property var termsRe: new RegExp(searchTerms.map(escapeTerm).join('|'), 'ig')
 
92
        readonly property string highlight: '<font color="%1">$&</font>'.arg("#752571")
 
93
 
 
94
        function escapeTerm(term) {
 
95
            // Escape special characters in a search term
 
96
            // (a simpler version of preg_quote).
 
97
            return term.replace(/[().?+|*^$]/g, '\\$&')
 
98
        }
 
99
 
 
100
        function highlightTerms(text) {
 
101
            // Highlight the matching terms in a case-insensitive manner
 
102
            if (text && text.toString()) {
 
103
                if (searchTerms.length == 0) {
 
104
                    return text
 
105
                }
 
106
                var highlighted = text.toString().replace(termsRe, highlight)
 
107
                highlighted = highlighted.replace(new RegExp('&', 'g'), '&amp;')
 
108
                highlighted = '<html>' + highlighted + '</html>'
 
109
                return highlighted
 
110
            } else {
 
111
                return ""
 
112
            }
 
113
        }
 
114
 
 
115
        function countItems(total, model) {
 
116
            return total + (model.hasOwnProperty("length") ? model.length : model.count)
 
117
        }
113
118
    }
114
119
}