JavaScript Bookmarklet Builder

[2014年1月27日更新:我在下面的脚本中修复了一个小bug我现在也正在托管它的副本在要点上]

那么一个书签是一个小的JavaScript脚本,旨在从Web浏览器的书签栏或菜单中运行他们作为“书签”工作的原因是JavaScript源代码使用“javascript:”方案塞进URL的形式。

至少可以说,开发或修改bookmarklet可能会令人恼火,因为JavaScript代码必须采用URL的形式。

For example, here’s a simple bit of JavaScript that (1) gets the title of the current web page; (2) shows an alert dialog with the title in all caps with an exclamation mark at the end.

var str = document.title;
alert(str.toUpperCase() + "!");

很简单但是同样的脚本,以书签的形式,看起来像这样(全部在一行):

// javascript:var%20str%20=%20document.title;
alert(str.toUpperCase()%20+%20%22!%22);

除了删除换行符之外,还需要转义空格(%20),也是逃避单引号和双引号的好主意。1您还需要转义非ASCII字符。

因此开发bookmarklet的问题是:您想要编写和编辑普通的JavaScript代码,但是您需要发布难以阅读的URL。

My solution: A “Make Bookmarklet” Perl script that I run as a BBEdit filter that (1) takes as input a file containing JavaScript source code; (2) creates a bookmarklet URL from that source code; and then (3) places the bookmarklet code in a comment at the first line of your JavaScript source, but otherwise preserves your original script.

所以,例如,鉴于这个简单的JavaScript:

var str = document.title;
alert(str);

我的“Make Bookmarklet”脚本将返回:

// javascript:var%20str%20=%20document.title;alert(str);
var str = document.title;
alert(str);

如果再次运行它,并在第一行开头注释“// javascript:“,它将取代该评论,而不是添加另一个评论我们的想法是,每次更改JavaScript代码时,都可以继续运行“Make Bookmarklet”脚本。

而且,作为额外的奖励,书签网址字符串是placed on the clipboard, which means you can run the script, and then immediately switch to your browser and paste it into the browser’s bookmarks editor.

源代码“制作Bookmarklet”脚本

#!/usr/bin/env perl
#
# http://www.gazogooz.com/2007/03/javascript_bookmarklet_builder

use strict;
use warnings;
use URI::Escape qw(uri_escape_utf8);
use open  IO  => ":utf8",       # UTF8 by default
          ":std";               # Apply to STDIN/STDOUT/STDERR

my $source_code = do { local $/; <> };

# Zap the first line if there's already a bookmarklet comment:
$source_code =~ s{^// ?javascript:.+\n}{};

my $bookmarklet = $source_code;
for ($bookmarklet) {
    s{(^\s*//.+\n)}{}gm;        # Kill commented lines
    s{^\s*/\*.+?\*/\n?}{}gms;   # Kill block comments
    s{\t}{ }gm;                 # Tabs to spaces
    s{[ ]{2,}}{ }gm;            # Space runs to one space
    s{^\s+}{}gm;                # Kill line-leading whitespace
    s{\s+$}{}gm;                # Kill line-ending whitespace
    s{\n}{}gm;                  # Kill newlines
}

# Escape single- and double-quotes, spaces, control chars, unicode:
$bookmarklet = "javascript:" .
    uri_escape_utf8($bookmarklet, qq(%'" \x00-\x1f\x7f-\xff));

print "// $bookmarklet\n"$source_code;

# Put bookmarklet on clipboard:
my $fh;
open($fh, '|-', '/usr/bin/pbcopy')
    or die "Failed to open pipe to /usr/bin/pbcopy - $!";
print $fh $bookmarklet
    or die "Failed to write to pbcopy pipe - $!";
close($fh)
    or die "Failed to close pipe to pbcopy - $!";

说明

以下是如何使用它的BBEdit要么的TextWrangler如果您使用其他编辑器,可能还有一些简单的方法可以在您的编辑器中使用shell脚本过滤器 - 此脚本中没有特定于BBEdit的内容(It ought to work as a service via的Automator要么ThisService也是,但我没试过。)

  1. 复制上面的Perl脚本并将其粘贴到新的文本窗口中。

  2. 把它保存在你的~/Library/Application Support/BBEdit/Text Filters/夹(Substitute “TextWrangler” for “BBEdit” if necessary.) I named mine “Make Bookmarklet”, but you can name it whatever you want.

  3. When run in a document window with a range of selected text, the selection will be passed as input and replaced with the outputIf no text is selected, the entire contents of the window will be used as input and replaced with the outputWith this script, it’s generally easiest to run it with no selection.

警告和反馈

自从我在2007年首次发布以来,这个脚本对我和其他许多人都有用但如果它吃了你的源代码,Undo就是你的朋友如果您发现任何错误或希望提出改进建议,请告诉我,或者把它放在Gist上


  1. 我不清楚是什么角色必须在bookmarklet URL中转义一些消息来源建议其他标点符号,如括号和分号,也应该被转义,但我认为没有实际的理由这样做如果你想要真正保守并且逃避一切,请改变这一行:

    uri_escape_utf8($ bookmarklet,qq(%'“\ x00- \ x1f \ x7f- \ xff));

    至:

    uri_escape_utf8($书签);

    Personally, I prefer to keep the bookmarklet URL itself as readable as possible. ↩︎