diff --git a/CHANGELOG b/CHANGELOG
new file mode 100644
index 0000000..f2580c4
--- /dev/null
+++ b/CHANGELOG
@@ -0,0 +1,10 @@
+1.1 2012-03-15
+---------------
+Load default settings if none exists.
+
+
+
+
+1.0 2012-03-15
+---------------
+First public release.
diff --git a/LICENSE b/LICENSE
new file mode 100644
index 0000000..fd30595
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,23 @@
+Copyright (c) 2012, Ching Chow
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without modification,
+are permitted provided that the following conditions are met:
+
+ * Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+
+ * Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
+ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/README b/README
new file mode 100644
index 0000000..3f9bf13
--- /dev/null
+++ b/README
@@ -0,0 +1,10 @@
+Lookup Assistant is an extension for the Google Chrome web browser that enables
+a user to perform search and other operations on highlighted text via the
+right-click menu. An options page allows customization of the menu to perform
+nearly any type of lookup operation for almost any website the user desires.
+Custom settings are saved using HTML5 local storage.
+
+* Simple and unobtrusive user interface.
+* User customizable menus.
+
+Available for free in the Chrome Web Store.
diff --git a/background.html b/background.html
new file mode 100644
index 0000000..94be966
--- /dev/null
+++ b/background.html
@@ -0,0 +1,43 @@
+
+
+
+
+
+
+ Lookup Assistant
+
+
+
+
+
+
+
+
diff --git a/chrome.png b/chrome.png
new file mode 100644
index 0000000..3ae2d44
Binary files /dev/null and b/chrome.png differ
diff --git a/html5.png b/html5.png
new file mode 100644
index 0000000..4e869d7
Binary files /dev/null and b/html5.png differ
diff --git a/javascript.png b/javascript.png
new file mode 100644
index 0000000..7b5ffab
Binary files /dev/null and b/javascript.png differ
diff --git a/json.gif b/json.gif
new file mode 100644
index 0000000..3bb55c8
Binary files /dev/null and b/json.gif differ
diff --git a/manifest.json b/manifest.json
new file mode 100644
index 0000000..f079f17
--- /dev/null
+++ b/manifest.json
@@ -0,0 +1,15 @@
+{
+ "name": "Lookup Assistant",
+ "version": "1.1",
+
+ "description": "Lookup highlighted text.",
+ "icons": {
+ "16": "monocle_16.png",
+ "48": "monocle_48.png",
+ "128": "monocle_128.png"
+ },
+
+ "background_page": "background.html",
+ "options_page": "options.html",
+ "permissions": ["contextMenus", "tabs"]
+}
diff --git a/monocle_128.png b/monocle_128.png
new file mode 100644
index 0000000..1c94c3d
Binary files /dev/null and b/monocle_128.png differ
diff --git a/monocle_16.png b/monocle_16.png
new file mode 100644
index 0000000..3610c88
Binary files /dev/null and b/monocle_16.png differ
diff --git a/monocle_48.png b/monocle_48.png
new file mode 100644
index 0000000..e958c0b
Binary files /dev/null and b/monocle_48.png differ
diff --git a/monocle_promo.png b/monocle_promo.png
new file mode 100644
index 0000000..8b4f745
Binary files /dev/null and b/monocle_promo.png differ
diff --git a/options.html b/options.html
new file mode 100644
index 0000000..5323936
--- /dev/null
+++ b/options.html
@@ -0,0 +1,282 @@
+
+
+
+
+
+
+ Lookup Assistant Menu Editor
+
+
+
+
+
Lookup Assistant Menu Editor
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Help
+
+
I. Buttons
+
+
+
Save: Save settings into local storage.
+
+
Load: Retrieve settings from local storage.
+
+
Exec: Execute the current settings shown in the text area without saving.
+
+
Wipe: Delete settings from local storage. Once deleted, an opportunity will be given to
+ restore the default settings.
+
+
+
II. Editing
+
+
+
Syntax: Lookup Assistant requires specific formatting for each of its entries.
+ This is done using standard JSON.
+
+
Overview: Whitespace (spaces, tabs, and newlines) doesn't matter, and can be
+ used to make things clearer and more readable. Lookup Assistant has three types: link,
+ menu, and separator. A menu can contain any of the three types. These must all be
+ contained within a pair of brackets. With the exception of a key's value, everything
+ should be typed in lowercase. Key-value pairs are explained below.
+
+ High-level View of Menu Formatting:
+
+[
+ link,
+ separator,
+ menu
+ link,
+ link
+]
+
+ Format and details of each type are explained below.
+
+
Link: This is the most common type. A link tells Lookup Assistant
+ where it should go and how it should get there. It's written in this format:
+
+ The opening and closing brace are required. Each item must be quoted, each key (the item
+ to the left of the colon) and its value (the item to the right) must be separated by a
+ colon, and a comma separates each key-value pair. An explanation of each key follows.
+
+ "type": This specifies the type. It can be "link", "menu", or "separator". You would,
+ of course, use "link" for links. However, this key is optional. The default behavior
+ is "link" if it's omitted.
+
+ "open": This determines how Lookup Assistant behaves when one of its links is clicked.
+ It can be one of three values: "tab", "window", or "incognito". This key is optional.
+ The default type is "tab" if it's omitted.
+
+ "title": The name for this link.
+
+ "address": The URL with a search token (%s). The search token will ultimately be replaced
+ by the highlighted text. To find out where the search token goes in a URL, go to a website
+ and perform a search to see what the URL looks like. Copy the URL and replace the search
+ term with the token. Some sites have very long and complex search URLs and may require
+ some effort.
+
+
Menu: This type is used for grouping and organization. A menu can contain any
+ type, even itself. It looks like this:
+
+ Regarding braces, quotes, and commas, the same rules apply here as they did with the link
+ type. The "type" and "title" keys also work the same way as they did for links, except
+ "type" is not optional here.
+
+ The new key is "entry", and the value is a pair of brackets. What's place between them
+ will determine what appears in this menu. Links, separators, and even additional menus
+ are all valid. See the link and separator section for proper formatting.
+
+
Separator: The simplest type. A separator only has a single key-value pair.
+ Like menus, specifying the type is required. It looks like this:
+
+{
+ "type": "separator"
+}
+
+ Separators will not appear if there is nothing to separate.
+ Having many nested menus can get quite confusing!
+
+
+
IV. Errors
+
+
+
SyntaxError: This error means there's something wrong with the JSON formatting.
+ Here are two common syntax errors and what they mean:
+
+
+
Unexpected end of input: The JSON formatting is incomplete. This may be caused
+ by a missing closing bracket.
+
+
Unexpected token X: X could be a bracket, a brace, or a comma. Usually, this
+ means there is something missing around X. Check areas where edits were made. Make
+ sure all open brackets have a proper closing bracket, and check for correctness in
+ braces and commas.
+
+ Checklist:
+
+
The very first thing is an open bracket [.
+
The very last thing is a closing bracket ].
+
All keys and values are quoted.
+
Each key and its value is separated by a colon.
+
Each pair is separated by a comma.
+
Types are also separated by a comma.
+
No comma after the last key-value pair.
+
No comma after the last type.
+
Menu entry uses brackets [], not braces {} and not parentheses ().
+
+
+ A good way to avoid these errors is to make small incremental changes and test them with
+ the exec button. Try not to make large changes all at once because it'll be hard to
+ pinpoint the source of the error.
+
+
Missing Property: This error means something was left out. e.g. Failure to
+ provide an address for the link type.
+
+
Unknown Type: This error means something other than link, menu, or separator
+ was specified as the type. Spelling errors will cause this error, as will improper
+ casing. i.e. link is not the same as Link.
+Copyright (c) 2012, smwst
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without modification,
+are permitted provided that the following conditions are met:
+
+ * Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+
+ * Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
+ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/screenshot_01.png b/screenshot_01.png
new file mode 100644
index 0000000..7cfc16e
Binary files /dev/null and b/screenshot_01.png differ
diff --git a/screenshot_02.png b/screenshot_02.png
new file mode 100644
index 0000000..d825178
Binary files /dev/null and b/screenshot_02.png differ
diff --git a/screenshot_03.png b/screenshot_03.png
new file mode 100644
index 0000000..7f813df
Binary files /dev/null and b/screenshot_03.png differ
diff --git a/scripts.js b/scripts.js
new file mode 100644
index 0000000..57593c6
--- /dev/null
+++ b/scripts.js
@@ -0,0 +1,300 @@
+// global abatement
+var LUA = {};
+
+// this array contains an object for each menu entry
+// links have three properties: address, id, and title
+// menus have two properties: id and title
+// separators are not included
+LUA.entry = [];
+
+// lookup the address of a given entry id, and replace the search token
+LUA.entry.getAddress = function (id, highlightedText) {
+ "use strict";
+ var i,
+ currency = /^(\d{1,3}(\,\d{3})*|\d+)(\.\d{1,2})?$/,
+ stripped = highlightedText.trim();
+ if (currency.test(stripped)) {
+ stripped = stripped.replace(/[,]/g, "");
+ }
+ for (i = 0; i < LUA.entry.length; i += 1) {
+ if (LUA.entry[i].id === id) {
+ return LUA.entry[i].address.replace("%s", stripped);
+ }
+ }
+};
+
+// lookup the id of a given entry title
+LUA.entry.getId = function (title) {
+ "use strict";
+ var i;
+ for (i = 0; i < LUA.entry.length; i += 1) {
+ if (LUA.entry[i].title === title) {
+ return LUA.entry[i].id;
+ }
+ }
+};
+
+// create various menu items
+LUA.create = {
+ link: function (address, open, title, parent) {
+ "use strict";
+ LUA.entry.push({
+ address: address,
+ id: chrome.contextMenus.create({
+ contexts: ["selection"],
+ onclick: (open === "window") ? LUA.open.window :
+ (open === "incognito") ? LUA.open.incognito : LUA.open.tab,
+ parentId: LUA.entry.getId(parent),
+ title: title
+ }),
+ title: title
+ });
+ },
+ menu: function (title, parent) {
+ "use strict";
+ LUA.entry.push({
+ id: chrome.contextMenus.create({
+ contexts: ["selection"],
+ parentId: LUA.entry.getId(parent),
+ title: title
+ }),
+ title: title
+ });
+ },
+ separator: function (parent) {
+ "use strict";
+ chrome.contextMenus.create({
+ contexts: ["selection"],
+ parentId: LUA.entry.getId(parent),
+ type: "separator"
+ });
+ }
+};
+
+// perform the lookup
+LUA.open = {
+ tab: function (info, tab) {
+ "use strict";
+ chrome.tabs.create({
+ url: LUA.entry.getAddress(info.menuItemId, info.selectionText)
+ });
+ },
+ window: function (info, tab) {
+ "use strict";
+ chrome.windows.create({
+ url: LUA.entry.getAddress(info.menuItemId, info.selectionText)
+ });
+ },
+ incognito: function (info, tab) {
+ "use strict";
+ chrome.windows.create({
+ url: LUA.entry.getAddress(info.menuItemId, info.selectionText),
+ incognito: true
+ });
+ }
+};
+
+// these buttons are for options.html and they manage local storage
+LUA.button = {
+ save: function () {
+ "use strict";
+ document.getElementById("status").innerHTML = " ";
+ if (confirm("Save current settings?")) {
+ LUA.settings.current = document.getElementById("editor").value;
+ localStorage.setItem("LUA_Settings", LUA.settings.current);
+ document.getElementById("status").innerHTML = "Settings saved.";
+ }
+ },
+ load: function () {
+ "use strict";
+ document.getElementById("status").innerHTML = " ";
+ if (confirm("Load saved settings?")) {
+ LUA.settings.current = localStorage.getItem("LUA_Settings");
+ document.getElementById("editor").value = LUA.settings.current;
+ document.getElementById("status").innerHTML = "Settings restored.";
+ }
+ },
+ exec: function () {
+ "use strict";
+ document.getElementById("status").innerHTML = " ";
+ LUA.settings.clearMenu();
+ LUA.settings.current = document.getElementById("editor").value;
+ if (LUA.settings.current.trim()) { // do not parse if there is no input
+ chrome.extension.sendRequest(
+ {
+ data: LUA.settings.current
+ },
+ function (error) {
+ if (error.name) {
+ document.getElementById("status").innerHTML = "" +
+ error.name + ": " + error.message +
+ (error.code ? "