From 03aea136eda20a6a6c85bb86836c33de05c6ea7b Mon Sep 17 00:00:00 2001 From: Jesse Rosalia Date: Sat, 28 Apr 2012 08:49:23 -0400 Subject: [PATCH 1/5] Initial firefox addon built using Addon SDK 1.6.1 --- extensions/firefox/README.md | 5 +++ extensions/firefox/data/tag-and-save.html | 19 +++++++++++ extensions/firefox/data/tag-and-save.js | 3 ++ extensions/firefox/doc/main.md | 2 ++ extensions/firefox/lib/main.js | 41 +++++++++++++++++++++++ extensions/firefox/package.json | 9 +++++ extensions/firefox/test/test-main.js | 32 ++++++++++++++++++ 7 files changed, 111 insertions(+) create mode 100644 extensions/firefox/README.md create mode 100644 extensions/firefox/data/tag-and-save.html create mode 100644 extensions/firefox/data/tag-and-save.js create mode 100644 extensions/firefox/doc/main.md create mode 100644 extensions/firefox/lib/main.js create mode 100644 extensions/firefox/package.json create mode 100644 extensions/firefox/test/test-main.js diff --git a/extensions/firefox/README.md b/extensions/firefox/README.md new file mode 100644 index 0000000..9a1b66a --- /dev/null +++ b/extensions/firefox/README.md @@ -0,0 +1,5 @@ +This is the imageindexer add-on. It contains: + +* A program (lib/main.js). +* A few tests. +* Some meager documentation. diff --git a/extensions/firefox/data/tag-and-save.html b/extensions/firefox/data/tag-and-save.html new file mode 100644 index 0000000..0075ad9 --- /dev/null +++ b/extensions/firefox/data/tag-and-save.html @@ -0,0 +1,19 @@ + + + + + + + + + + + + + + diff --git a/extensions/firefox/data/tag-and-save.js b/extensions/firefox/data/tag-and-save.js new file mode 100644 index 0000000..a5f02ff --- /dev/null +++ b/extensions/firefox/data/tag-and-save.js @@ -0,0 +1,3 @@ +self.port.on("show", function(arg) { + document.getElementById('tgt_image').src = arg; +}); diff --git a/extensions/firefox/doc/main.md b/extensions/firefox/doc/main.md new file mode 100644 index 0000000..4dff065 --- /dev/null +++ b/extensions/firefox/doc/main.md @@ -0,0 +1,2 @@ +The main module is a program that creates a widget. When a user clicks on +the widget, the program loads the mozilla.org website in a new tab. diff --git a/extensions/firefox/lib/main.js b/extensions/firefox/lib/main.js new file mode 100644 index 0000000..74b1662 --- /dev/null +++ b/extensions/firefox/lib/main.js @@ -0,0 +1,41 @@ +const widgets = require("widget"); +const tabs = require("tabs"); +const cm = require("context-menu"); +const data = require("self").data; + +var widget = widgets.Widget({ + id: "mozilla-link", + label: "Mozilla website", + contentURL: "http://www.mozilla.org/favicon.ico", + onClick: function() { + tabs.open("http://www.mozilla.org/"); + } +}); + +cm.Item({ + label: "Save Image", + context: cm.SelectorContext("img"), + contentScript: 'self.on("click", function (node, data) {' + + ' self.postMessage(node.src);' + + '});', + onMessage: function (imgSrc) { + openTagAndSave(imgSrc); + } +}); + +openTagAndSave = function(imageSrc) { + + var panel = require("panel").Panel({ + width: 360, + height: 180, + contentURL: data.url('tag-and-save.html'), + contentScriptFile: data.url('tag-and-save.js') + }); + + panel.on("show", function() { + panel.port.emit("show", imageSrc); + }); + + panel.show(); +} +console.log("The add-on is running."); diff --git a/extensions/firefox/package.json b/extensions/firefox/package.json new file mode 100644 index 0000000..6662d47 --- /dev/null +++ b/extensions/firefox/package.json @@ -0,0 +1,9 @@ +{ + "name": "imageindexer", + "license": "MPL 2.0", + "author": "", + "version": "0.1", + "fullName": "imageindexer", + "id": "jid1-dMw3JDjmiByCzA", + "description": "a basic add-on" +} diff --git a/extensions/firefox/test/test-main.js b/extensions/firefox/test/test-main.js new file mode 100644 index 0000000..98d630b --- /dev/null +++ b/extensions/firefox/test/test-main.js @@ -0,0 +1,32 @@ +const main = require("main"); + +exports.test_test_run = function(test) { + test.pass("Unit test running!"); +}; + +exports.test_id = function(test) { + test.assert(require("self").id.length > 0); +}; + +exports.test_url = function(test) { + require("request").Request({ + url: "http://www.mozilla.org/", + onComplete: function(response) { + test.assertEqual(response.statusText, "OK"); + test.done(); + } + }).get(); + test.waitUntilDone(20000); +}; + +exports.test_open_tab = function(test) { + const tabs = require("tabs"); + tabs.open({ + url: "http://www.mozilla.org/", + onReady: function(tab) { + test.assertEqual(tab.url, "http://www.mozilla.org/"); + test.done(); + } + }); + test.waitUntilDone(20000); +}; From 861871292730958e75cdce44699e8d49e308fca4 Mon Sep 17 00:00:00 2001 From: Jesse Rosalia Date: Sat, 28 Apr 2012 12:15:12 -0400 Subject: [PATCH 2/5] implemted panel for both widget (bottom of the window) and right click menu...right click will preset the image in the panel. drag and drop, clicking on image box to select the image. style-upload.js lets us style the page so that it looks right in the panel --- extensions/firefox/data/style-upload.js | 15 ++++++++++ extensions/firefox/lib/main.js | 38 ++++++++++++++----------- 2 files changed, 36 insertions(+), 17 deletions(-) create mode 100644 extensions/firefox/data/style-upload.js diff --git a/extensions/firefox/data/style-upload.js b/extensions/firefox/data/style-upload.js new file mode 100644 index 0000000..cbb675a --- /dev/null +++ b/extensions/firefox/data/style-upload.js @@ -0,0 +1,15 @@ +self.port.on("show", function(arg) { + //create the css style sheet...we'll style the upload form using this style + //sheet + var style = document.createElement('style'); + style.type = 'text/css'; + + document.getElementsByTagName('head')[0].appendChild(style); + + style.innerHTML = 'body {margin: 0px; padding: 0px}'; + style.innerHTML = style.innerHTML + 'li { display: inline; list-style-type: none; padding-right: 20px; }'; + style.innerHTML = style.innerHTML + '#label_list {display: inline}'; + style.innerHTML = style.innerHTML + '#image {display: inline-block}'; + style.innerHTML = style.innerHTML + '#fileselect {display: none}'; + style.innerHTML = style.innerHTML + '#submitbutton {float: left}'; +}); diff --git a/extensions/firefox/lib/main.js b/extensions/firefox/lib/main.js index 74b1662..a1a0def 100644 --- a/extensions/firefox/lib/main.js +++ b/extensions/firefox/lib/main.js @@ -3,17 +3,31 @@ const tabs = require("tabs"); const cm = require("context-menu"); const data = require("self").data; +var baseURL = 'http://localhost:3000/upload'; +function createLabelousPanel(url) { + console.log('Creating a panel with url: ' + url); + var panel = require("panel").Panel({ + width: 360, + height: 180, + contentURL: url, + contentScriptFile: data.url('style-upload.js') + }); + panel.on("show", function() { + panel.port.emit("show"); + }); + return panel; +} + +var widgetPanel = createLabelousPanel(baseURL); var widget = widgets.Widget({ - id: "mozilla-link", - label: "Mozilla website", + id: "labelous-widget", + label: "Labelo.us", contentURL: "http://www.mozilla.org/favicon.ico", - onClick: function() { - tabs.open("http://www.mozilla.org/"); - } + panel: createLabelousPanel(baseURL) }); cm.Item({ - label: "Save Image", + label: "Send to labelo.us...", context: cm.SelectorContext("img"), contentScript: 'self.on("click", function (node, data) {' + ' self.postMessage(node.src);' + @@ -25,17 +39,7 @@ cm.Item({ openTagAndSave = function(imageSrc) { - var panel = require("panel").Panel({ - width: 360, - height: 180, - contentURL: data.url('tag-and-save.html'), - contentScriptFile: data.url('tag-and-save.js') - }); - - panel.on("show", function() { - panel.port.emit("show", imageSrc); - }); - + var panel = createLabelousPanel(baseURL + "?url=" + imageSrc); panel.show(); } console.log("The add-on is running."); From 17c9cc660a25d3d8c1e2572e6ce8b33edbeaa415 Mon Sep 17 00:00:00 2001 From: Jesse Rosalia Date: Sat, 28 Apr 2012 12:23:04 -0400 Subject: [PATCH 3/5] Added layout to upload.jade (for easy styling), pulled out and cleaned up drag and drop functionality, added style-upload sandbox (for playing with extension-specific styles) --- server/app.js | 1 + server/public/javascript/dragdrop.js | 119 +++++++++++++++++++++++ server/public/javascript/style-upload.js | 18 ++++ server/public/javascript/upload.js | 33 +++++++ server/routes/index.js | 7 +- server/views/index.jade | 22 ++++- server/views/layout.jade | 6 +- server/views/upload.jade | 29 ++++++ 8 files changed, 231 insertions(+), 4 deletions(-) create mode 100644 server/public/javascript/dragdrop.js create mode 100644 server/public/javascript/style-upload.js create mode 100644 server/public/javascript/upload.js create mode 100644 server/views/upload.jade diff --git a/server/app.js b/server/app.js index 2f7538a..4c84510 100644 --- a/server/app.js +++ b/server/app.js @@ -30,6 +30,7 @@ app.configure('production', function(){ // Routes app.get('/', routes.index); +app.get('/upload', routes.upload); app.listen(3000, function(){ console.log("Express server listening on port %d in %s mode", app.address().port, app.settings.env); diff --git a/server/public/javascript/dragdrop.js b/server/public/javascript/dragdrop.js new file mode 100644 index 0000000..e2d4a39 --- /dev/null +++ b/server/public/javascript/dragdrop.js @@ -0,0 +1,119 @@ +/* + * Javascript classes to install and support HTML5 Image support + * This support includes: + * Image select w/ preview + * Drag and drop w/ preview + * + */ +function InstallHTML5ImageDragDrop(drag_div_id, image_id) { + + var imagediv = $("#" + image_id); + var filedrag = $("#" + drag_div_id); + + if (!window.File || !window.FileList || !window.FileReader || !imagediv || !filedrag) { + return; + } + + // is XHR2 available? + var xhr = new XMLHttpRequest(); + if (xhr.upload) { + var _this = this; + // file drop + filedrag.on("dragover", FileDragHover); + filedrag.on("dragleave", FileDragHover); + filedrag.on("drop", function(e) { + FileSelectHandler(e, function(e, file) { + OnImageDrop(e, file, imagediv); + }); + }); + //filedrag.style.display = "block"; + // remove submit button + // submitbutton.style.display = "none"; + } +} + +function InstallHTML5ImageSelect(select_input_id, image_id, click_div_id) { + var imagediv = $("#" + image_id); + var fileselect = $("#" + select_input_id); + + if (!window.File || !window.FileList || !window.FileReader || !imagediv || !fileselect) { + return; + } + + + // file select + fileselect.on("change", function(e) { + FileSelectHandler(e, function(e, file) { + OnImageDrop(e, file, imagediv); + }); + }); + + if (click_div_id) { + var clickdiv = $("#" + click_div_id); + clickdiv.on("click", function(e) { + fileselect.click(); + }); + } +} + +function OnImageDrop(e, file, image) { + // Render thumbnail. + this.image.attr("src", e.target.result); +// var span = document.createElement('span'); +// span.innerHTML = [''].join(''); +// document.getElementById('list').insertBefore(span, null); + +} + +/*** Generic File Handler methods ***/ + +// +// output information +function Output(msg) { + var m = $("#messages"); + m.html(msg + m.html()); +} + +// file drag hover +function FileDragHover(e) { + e.stopPropagation(); + e.preventDefault(); + e.target.className = (e.type == "dragover" ? "hover" : ""); +} + +// file selection +function FileSelectHandler(e, file_load_func) { + e = e.originalEvent || e; + // cancel event and hover styling + FileDragHover(e); + // fetch FileList object + + var files = e.target.files || e.dataTransfer.files; + // process all File objects + for (var i = 0, + f; f = files[i]; + i++) { + var reader = new FileReader(); + + // Closure to capture the file information. + reader.onload = (function(theFile) { + return function(e) { + file_load_func(e, theFile); + }; + })(f); + + // Read in the image file as a data URL. + reader.readAsDataURL(f); + + } +} + +function ParseFile(file) { + Output( + "

File information: " + file.name + + " type: " + file.type + + " size: " + file.size + + " bytes

" + ); +} diff --git a/server/public/javascript/style-upload.js b/server/public/javascript/style-upload.js new file mode 100644 index 0000000..1ae7e31 --- /dev/null +++ b/server/public/javascript/style-upload.js @@ -0,0 +1,18 @@ +$(function() { + +//create the css style sheet...we'll style the upload form using this style +//sheet +var style = document.createElement('style'); +style.type = 'text/css'; + +document.getElementsByTagName('head')[0].appendChild(style); + + +style.innerHTML = 'body {margin: 0px; padding:0px}'; +style.innerHTML = style.innerHTML + 'li { display: inline; list-style-type: none; padding-right: 20px; }'; +style.innerHTML = style.innerHTML + '#label_list {display: inline}'; +style.innerHTML = style.innerHTML + '#image {display: inline-block}'; +style.innerHTML = style.innerHTML + '#fileselect {display: none}'; +style.innerHTML = style.innerHTML + '#submitbutton {float: left}'; + +}); diff --git a/server/public/javascript/upload.js b/server/public/javascript/upload.js new file mode 100644 index 0000000..5815130 --- /dev/null +++ b/server/public/javascript/upload.js @@ -0,0 +1,33 @@ + + function getUrlVars() + { + var vars = [], hash; + var hashes = window.location.href.slice(window.location.href.indexOf('?') + 1).split('&'); + for(var i = 0; i < hashes.length; i++) + { + hash = hashes[i].split('='); + vars.push(hash[0]); + vars[hash[0]] = hash[1]; + } + return vars; + } + + function PresetUrl(image_id) { + var vars = getUrlVars(); + $('#' + image_id).attr("src", vars['url']); + } + + function label_input_keypress(e) { + if ( e.keyCode == 13 || e.keyCode == 32 || e.keyCode == 44) { + var label_text = $('#label_input').val(); + add_label(label_text); + $('#label_input').val(''); + e.preventDefault(); + } + } + + function add_label(label_text) { + var label = $('
  • '); + label.text(label_text); + $('#label_list').append(label); + } diff --git a/server/routes/index.js b/server/routes/index.js index fd69215..f9b9ff8 100644 --- a/server/routes/index.js +++ b/server/routes/index.js @@ -5,4 +5,9 @@ exports.index = function(req, res){ res.render('index', { title: 'Express' }) -}; \ No newline at end of file +}; + +exports.upload = function(req, res) { + console.log(req.query); + res.render('upload', { title: 'Express' }) +} diff --git a/server/views/index.jade b/server/views/index.jade index c9c35fa..a5804aa 100644 --- a/server/views/index.jade +++ b/server/views/index.jade @@ -1,2 +1,20 @@ -h1= title -p Welcome to #{title} \ No newline at end of file +#upload + form(action="/upload", method="POST") + #filedrag(style='width:200px;height:200px') + img#tgt_image(style='width:200px;height:200px', src='#') + input(type="file", id="fileselect", name="fileselect[]", multiple="multiple") + + ul#label_list + input#label_input(type='text') + script(type='text/javascript') + $('#label_input').on('keypress', function(e) { + label_input_keypress(e); + }); + //TODO: pull url out of page params + + #submitbutton + input(type="submit") + button(id="cancelButton") Cancel + + #messages + \ No newline at end of file diff --git a/server/views/layout.jade b/server/views/layout.jade index 1a36941..af43530 100644 --- a/server/views/layout.jade +++ b/server/views/layout.jade @@ -3,4 +3,8 @@ html head title= title link(rel='stylesheet', href='/stylesheets/style.css') - body!= body \ No newline at end of file + script(type='text/javascript', src='http://ajax.googleapis.com/ajax/libs/jquery/1.7.0/jquery.min.js') + script(type='text/javascript', src='javascript/upload.js') + script(type='text/javascript', src='javascript/dragdrop.js') + script(type='text/javascript', src='javascript/style-upload.js') + body!= body diff --git a/server/views/upload.jade b/server/views/upload.jade new file mode 100644 index 0000000..9e0e7ac --- /dev/null +++ b/server/views/upload.jade @@ -0,0 +1,29 @@ +#upload + form(action="/upload", method="POST") + #main_form + #image + #filedrag(style='width:200px;height:200px;border:1px solid') + img#tgt_image(style='width:200px;height:200px') + input(type="file", id="fileselect", name="fileselect[]", multiple="multiple") + + #label + ul#label_list + input#label_input(type='text') + + + #buttons + #submitbutton + input(type="submit") + button(id="cancelButton") Cancel + + #messages + + script(type='text/javascript') + InstallHTML5ImageDragDrop('filedrag', 'tgt_image'); + InstallHTML5ImageSelect ('fileselect', 'tgt_image', 'filedrag'); + + $('#label_input').on('keypress', function(e) { + label_input_keypress(e); + }); + + $(document).ready(function() {PresetUrl('tgt_image');}); From 182980f1c4a9d3660d7772e8e955478fbfbbdadf Mon Sep 17 00:00:00 2001 From: Jesse Rosalia Date: Sat, 28 Apr 2012 12:24:36 -0400 Subject: [PATCH 4/5] ignore backup files --- extensions/firefox/.gitignore | 8 ++++++++ 1 file changed, 8 insertions(+) create mode 100644 extensions/firefox/.gitignore diff --git a/extensions/firefox/.gitignore b/extensions/firefox/.gitignore new file mode 100644 index 0000000..1648267 --- /dev/null +++ b/extensions/firefox/.gitignore @@ -0,0 +1,8 @@ +{ + "name": "imageindexer", + "fullName": "imageindexer", + "description": "a basic add-on", + "author": "", + "license": "MPL 2.0", + "version": "0.1" +} From ca4ec3f8a53bd0ab19a26341136ccf37c1252148 Mon Sep 17 00:00:00 2001 From: Jesse Rosalia Date: Sat, 28 Apr 2012 12:26:51 -0400 Subject: [PATCH 5/5] whoops, wrote content in .gitignore --- extensions/firefox/.gitignore | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/extensions/firefox/.gitignore b/extensions/firefox/.gitignore index 1648267..110662c 100644 --- a/extensions/firefox/.gitignore +++ b/extensions/firefox/.gitignore @@ -1,8 +1 @@ -{ - "name": "imageindexer", - "fullName": "imageindexer", - "description": "a basic add-on", - "author": "", - "license": "MPL 2.0", - "version": "0.1" -} +package.json.backup