diff --git a/extensions/firefox/.gitignore b/extensions/firefox/.gitignore new file mode 100644 index 0000000..110662c --- /dev/null +++ b/extensions/firefox/.gitignore @@ -0,0 +1 @@ +package.json.backup 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/style-upload.js b/extensions/firefox/data/style-upload.js new file mode 100644 index 0000000..fb4f71e --- /dev/null +++ b/extensions/firefox/data/style-upload.js @@ -0,0 +1,16 @@ +self.port.on('show', function(img_width, img_height) { + //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; padding: 0.5em 1em;}'; + style.innerHTML = style.innerHTML + '#label_list {display: inline; padding-left:0px}'; + style.innerHTML = style.innerHTML + '#filedrag {width: ' + img_width + 'px; height: ' + img_height + 'px; border: 1px solid;}'; + 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/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..048af00 --- /dev/null +++ b/extensions/firefox/lib/main.js @@ -0,0 +1,51 @@ +const widgets = require("widget"); +const tabs = require("tabs"); +const cm = require("context-menu"); +const data = require("self").data; + +var width = 360; +var height = 180; + +var thumb_width = width / 2; +var thumb_height = height - 60; + +var baseURL = 'http://localhost:3000/upload'; +function createLabelousPanel(url) { + console.log('Creating a panel with url: ' + url); + var panel = require("panel").Panel({ + width: width, + height: height, + contentURL: url, + contentScriptFile: data.url('style-upload.js') + }); + panel.on("show", function() { + panel.port.emit("show", thumb_width, thumb_height); + }); + return panel; +} + +var widgetPanel = createLabelousPanel(baseURL); +var widget = widgets.Widget({ + id: "labelous-widget", + label: "Labelo.us", + contentURL: "http://www.mozilla.org/favicon.ico", + panel: createLabelousPanel(baseURL) +}); + +cm.Item({ + label: "Send to labelo.us...", + 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 = createLabelousPanel(baseURL + "?url=" + 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); +}; 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..5e93730 --- /dev/null +++ b/server/public/javascript/style-upload.js @@ -0,0 +1,16 @@ +function styleUploadForm(img_width, img_height) { + //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; padding: 0.5em 1em;}'; + style.innerHTML = style.innerHTML + '#label_list {display: inline; padding-left:0px}'; + style.innerHTML = style.innerHTML + '#filedrag {width: ' + img_width + 'px; height: ' + img_height + 'px; border: 1px solid;}'; + 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..7ce0f58 --- /dev/null +++ b/server/public/javascript/upload.js @@ -0,0 +1,40 @@ + + 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) { + var input = $('#label_input'); + var code = e.keyCode || e.charCode; + if (code == 13 || code == 32 || code == 33 || code == 44 || code == 46 || code == 63) { + var label_text = input.val(); + if (label_text != '') { + add_label(label_text); + input.val(''); + } + e.preventDefault(); + } + } + + function add_label(label_text) { + var label = $('
  • '); + label.on("click", function(e) { + label.remove(); + }); + 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..28707f7 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 + 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 + 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..85454f3 --- /dev/null +++ b/server/views/upload.jade @@ -0,0 +1,30 @@ +#upload + form(action="/upload", method="POST") + #main_form + #image + #filedrag + img#tgt_image + 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');}); + styleUploadForm(32, 24);