AppleScript/JavaSript 在 Safari 中突出显示匹配的文本

AppleScript/JavaSript to highlight matched text in Safari

我有以下脚本,它将从剪贴板中获取一些值,return 它们分别,并突出显示当前 safari 中的匹配文本 window :

set myNewList to {}

set myClipboard to the clipboard
set theList to words of myClipboard
##set theLength to (get length of mylist)


set ColortheList to {"009933", "000000", "660066", "660099", "003399", "0033ff", "336666", "339966", "339999", "3399cc", "3399ff", "33cc66", "006633", "006666", "006699", "0066cc", "33ffff", "9933cc", "0066ff", "009966", "3366ff", "993300", "993333", "339900", "009999", "0099cc", "0099ff", "6600cc", "6600ff", "663300", "663333", "663366", "9900ff", "663399", "6633cc", "6633ff", "666699", "00cc00", "339933", "00cc33", "00cc66", "00cc99", "00cccc", "993366", "00ccff", "00ff00", "336699", "ff3333", "3366cc", "00ff33", "33ff00", "6666cc", "6666ff", "ff9999", "669966", "66ff99", "993399", "990066", "990099", "9900cc", "ff0099", "66ffcc", "33ff33", "00ff66", "ffcccc", "33cc99", "ff66cc", "33cccc", "33ccff", "00ff99", "00ffcc", "33ffcc", "00ffff", "330066", "330099", "3300cc", "ff9999", "3300ff", "33ff66", "990033", "33ff99", "333300", "333333", "3333ff", "336600", "660000", "660033", "66ffff", "990000", "9933ff", "996600", "996666", "996699", "9966cc", "9966ff"}


repeat with a from 1 to length of theList
    copy ({item a of theList, some item of ColortheList}) to the end of the |myNewList|
    
end repeat



tell application "Safari"
    ## activate
    set theWindow to front window
    tell theWindow
        tell current tab
            repeat with colourPair in myNewList
                do JavaScript "document.designMode = 'on'"
                do JavaScript "var sel = window.getSelection(); sel.collapse(document.body, 0); while (window.find('" & (item 1 of colourPair) & "', true)) {document.execCommand('HiliteColor', false, '" & (item 2 of colourPair) & "');}"
                do JavaScript "document.designMode = 'off'"
            end repeat
        end tell
        
    end tell
end tell

这工作正常,但速度很慢,尤其是当我有 10 个以上的变量时。 最重要的是,如果我不小心按下键盘上的某个键,它会更改 safari 上加载的页面内容,如果我在 运行 时更改点击,也会出错。

它们是加速脚本和改进代码的方法吗?

查看您发布的代码,以下示例 AppleScript code 是我重写你的 code 以加快速度的方式:

set myNewList to {}

set theList to words of (the clipboard)

set AppleScript's text item delimiters to linefeed
set tempList to theList as string
set AppleScript's text item delimiters to ""

set theSortedUniqList to paragraphs of ¬
    (do shell script "sort -u <<< " & tempList's quoted form)   

set ColortheList to {"009933", "000000", "660066", "660099", "003399", "0033ff", "336666", "339966", "339999", "3399cc", "3399ff", "33cc66", "006633", "006666", "006699", "0066cc", "33ffff", "9933cc", "0066ff", "009966", "3366ff", "993300", "993333", "339900", "009999", "0099cc", "0099ff", "6600cc", "6600ff", "663300", "663333", "663366", "9900ff", "663399", "6633cc", "6633ff", "666699", "00cc00", "339933", "00cc33", "00cc66", "00cc99", "00cccc", "993366", "00ccff", "00ff00", "336699", "ff3333", "3366cc", "00ff33", "33ff00", "6666cc", "6666ff", "ff9999", "669966", "66ff99", "993399", "990066", "990099", "9900cc", "ff0099", "66ffcc", "33ff33", "00ff66", "ffcccc", "33cc99", "ff66cc", "33cccc", "33ccff", "00ff99", "00ffcc", "33ffcc", "00ffff", "330066", "330099", "3300cc", "ff9999", "3300ff", "33ff66", "990033", "33ff99", "333300", "333333", "3333ff", "336600", "660000", "660033", "66ffff", "990000", "9933ff", "996600", "996666", "996699", "9966cc", "9966ff"}

repeat with anItem in theSortedUniqList
    copy {anItem, some item of ColortheList} to the end of the myNewList
end repeat

tell application "Safari"
    tell current tab of front window
        do JavaScript "document.designMode = 'on'"
        repeat with colourPair in myNewList
            do JavaScript "var sel = window.getSelection(); sel.collapse(document.body, 0); while (window.find('" & (item 1 of colourPair) & "', true)) {document.execCommand('HiliteColor', false, '" & (item 2 of colourPair) & "');}"
        end repeat
        do JavaScript "document.designMode = 'off'"
    end tell
end tell

备注:

我确实做了一些计时测试,通过不必为 item 中的每个 do JavaScript "document.designMode = 'on'"do JavaScript "document.designMode = 'off'" 调用 do JavaScript "document.designMode = 'on'"do JavaScript "document.designMode = 'off'" 有了一些改进=32=]list 在第二个 repeat loop.

添加了 code 以使 list 排序和 uniq 以避免处理可能在剪贴板上的任何重复单词。

还写了第一个 repeat loop 因为我已经否定了计算列表长度的需要,因为它是无关紧要的,并且削减了很小一部分第二关。

这个项目并没有加快速度,但我也删除了不必要的字符,例如,圆括号竖线.

我也使用 set theList to words of (the clipboard) 而不是你用来获得相同结果的两行 codeset myClipboard to the clipboardset theList to words of myClipboard 只是为了减少要编写的 code 的数量,IMO 只是更容易阅读,因为它减少了 code 的数量也阅读和维护。

虽然 @user3439894 提供的答案肯定比他问题中 OP 的代码更有效,但他的解决方案可以优化得更多。

我从这个资源中学到的解决方案中的优化…

Learn AppleScript - The Comprehensive Guide to Scripting and Automation on Mac OS X, Third Edition

以下摘录直接取自我上面提到的资源,是我复制到剪贴板的内容,将在我的优化代码中进行处理。

In theory, no matter how long the list is, the lookup time should be the same every time, but when we look at the results, we see that the time it takes to get the list item grows twice as large each time we double the size of the list—a linear increase, in other words, or O(n) efficiency. So if, for example, we were writing a script to loop over a variable number of items in a list, we would see the time it takes increase quadratically compared to the number of items in the list, or O(n*n). Ouch! That could really start to bite if you have, say, several thousand items to get through, perhaps even becoming the major performance bottleneck in your code. Fortunately, there is a “solution” of sorts that tricks AppleScript lists into performing constant-time lookups. If you wrap up your list in a script object property and refer to it there, something in the way that AppleScript references work causes whatever piece of the interpreter that is causing the slowdown to be bypassed.

set startTime to current date

set theList to words of (the clipboard)
log ((count of theList) as text) & " Words From Clipboard Processed"

set ColortheList to {"009933", "000000", "660066", "660099", "003399", "0033ff", "336666", "339966", "339999", "3399cc", "3399ff", "33cc66", "006633", "006666", "006699", "0066cc", "33ffff", "9933cc", "0066ff", "009966", "3366ff", "993300", "993333", "339900", "009999", "0099cc", "0099ff", "6600cc", "6600ff", "663300", "663333", "663366", "9900ff", "663399", "6633cc", "6633ff", "666699", "00cc00", "339933", "00cc33", "00cc66", "00cc99", "00cccc", "993366", "00ccff", "00ff00", "336699", "ff3333", "3366cc", "00ff33", "33ff00", "6666cc", "6666ff", "ff9999", "669966", "66ff99", "993399", "990066", "990099", "9900cc", "ff0099", "66ffcc", "33ff33", "00ff66", "ffcccc", "33cc99", "ff66cc", "33cccc", "33ccff", "00ff99", "00ffcc", "33ffcc", "00ffff", "330066", "330099", "3300cc", "ff9999", "3300ff", "33ff66", "990033", "33ff99", "333300", "333333", "3333ff", "336600", "660000", "660033", "66ffff", "990000", "9933ff", "996600", "996666", "996699", "9966cc", "9966ff"}

colorWords(theList, ColortheList)

on colorWords(someList, ColortheList)
    script fasterList
        property aList : someList
        property coloredList : ColortheList
        property myNewList : {}
    end script
    repeat with anItem in fasterList's aList
        copy {anItem, some item of fasterList's coloredList} to the end of fasterList's myNewList
    end repeat
    
    tell application "Safari"
        tell current tab of front window
            do JavaScript "document.designMode = 'on'"
            repeat with colourPair in fasterList's myNewList
                do JavaScript "var sel = window.getSelection(); sel.collapse(document.body, 0); while (window.find('" & (item 1 of colourPair) & "', true)) {document.execCommand('HiliteColor', false, '" & (item 2 of colourPair) & "');}"
            end repeat
            do JavaScript "document.designMode = 'off'"
        end tell
    end tell
end colorWords

set timeTaken to ((current date) - startTime as string) & " Seconds"

下图显示了处理剪贴板中的 183 个单词的结果。左图是我的优化技术的结果,右图是“Accepted Answer”的结果

处理剪贴板中的183个单词显示两者之间有13秒的时间差。这不是很大的区别,但看看当剪贴板包含 414 个单词时会发生什么。哎哟!

一般来说,待处理的列表越大,右图中的代码效率越低。

为了不让这个post被不必要的文字塞满,为下一次测试添加到我的剪贴板的414个单词就是从这里拿来的。 (这是直接从我上面提到的资源中摘录的内容的续集。)

由于我使用了 user3439894 的代码作为构建基础,我认为他应该获得“已接受答案”的功劳

无论如何,我 posted 的方法要快得多。

您可能还需要考虑添加额外的代码,以便在将这些项目传递给要处理的脚本的其余部分之前从剪贴板中删除任何重复的单词