mirror of
http://git.whoc.org.uk/git/password-manager.git
synced 2024-11-14 18:49:03 +01:00
07d0357bee
- updated reference dates; - removed reference to Community Edition; - normalized logging using Clipperz.log[Warn|Error|Debug]
763 lines
24 KiB
JavaScript
763 lines
24 KiB
JavaScript
/*
|
|
|
|
Copyright 2008-2013 Clipperz Srl
|
|
|
|
This file is part of Clipperz, the online password manager.
|
|
For further information about its features and functionalities please
|
|
refer to http://www.clipperz.com.
|
|
|
|
* Clipperz is free software: you can redistribute it and/or modify it
|
|
under the terms of the GNU Affero General Public License as published
|
|
by the Free Software Foundation, either version 3 of the License, or
|
|
(at your option) any later version.
|
|
|
|
* Clipperz is distributed in the hope that it will be useful, but
|
|
WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
|
See the GNU Affero General Public License for more details.
|
|
|
|
* You should have received a copy of the GNU Affero General Public
|
|
License along with Clipperz. If not, see http://www.gnu.org/licenses/.
|
|
|
|
*/
|
|
|
|
clipperz_copiedContentToClipboard = false;
|
|
|
|
//#############################################################################
|
|
|
|
// Simple Set Clipboard System
|
|
// Author: Joseph Huckaby
|
|
|
|
var ZeroClipboard = {
|
|
|
|
version: "1.0.4",
|
|
clients: {}, // registered upload clients on page, indexed by id
|
|
// moviePath: 'ZeroClipboard.swf', // URL to movie
|
|
// moviePath: 'data:application/octet-stream;charset=utf-8;base64,Q1dTCYgGAAB4nH1V61LbRhTeXV2OJNsYczFgIEC4JCGABSRpSy+B2JDQQtWJocl0BqK1tUZqhOSRZAj/8ih9hz5AXsGZTl+ndHUhxU2nO56z3/l05uye7+wc6xr6DeUxqpcUhFCNXF9ffxjNcYhRo8U8NruO0IeRLTkm+BpEa4i8/+t3GRGUrRf5tktDe41dMC8Kpd14Q/DM911GPfHCd6zCLyzwa67Tafo0sAppuOWEHZdeyY1O4ERMbnajyPcKIYteUM+qdYPQD/It12m9jX2XBcSx5EYUON6ZwunOEXsXAY+O94HsAu8iFnjULe1mYN/je5u2WLnvAsnRNGrZ6rnfDZlxwQKxRV1XSd1ulPJ1/9KDBB13pDCiZ2ygEdsGj2WHvsXU3dc7taM3e/tHanjDZVqEV2HEzpUGa3V5dVd4Ocfz+5d1/5w6nnbgU4sF+17bFwPfjzT3k691aEDPGb92KBvNX1krmrOjqLNVrVLLb7K1ln9e3WlsVjd0/Um12XXcyPFy6ZHdyHHDkT5tt1JtF/rJerqn6Wu+F/ErsWCmPyiRjrYi54KlgZP/k2Tq9gPYSh5APZOYBVra2VicAtfyn+4qZwHt2E4rVJvszPH2HNcVD2lkS5eOxW3b9f1AtplzZkeKFdDLl/wkibodmyrUsmq241raYdye5ECpdrBf+2GQf0ncA4c3gJelHRrHjd03xs+7L9UMHh9lZN149aOSwuOfcnFO3qQmbb0V44aoSVEXlHeikXQzz1/bpzek8E50XN6o4r/KLfQpU/pMx/J/yz9cxmWhDOOyhMqD5SkJjQnKYnmpIlfuVe5XHlSWKw8rC6QoEayoWk7MFwaKg6Whx4AJEBGIBEQGQQFJBaKBlAMpD6QA0gCQIsglICNAxkGYAFIBMgkwDWQGhFkgc0DuApkHsqDmMZAVIKtA1oBUgejqOmc21E1uHwF5DOQJ4C+AfAnkKyBbQL4G8g2Qb4F8B+o2wA6QZ4DrIOyCsAfCcw0lUwR/ZvgiOP3IhwgWcDZIsCipIpJkPmskBBiBgpGiIqQJOJdYPqbiOaRiUcRIQ5hrIfT055ySiKYVzMLKkKmuDM8aAyInyW1yNCOF22Q5I8Xb5FhGSjLR8n/gnv5q+U+9t4/MojnYLtEhc3jljjGCGT4Z7bXL7bG9Udwefz9xjk9Vhl3crtjqqXwifS8hWzblJToZmylTbk+vYuMOjsECWjZnkuDZvTmcwbscGvOiKVcxXThZNGVjkQebS+17pmLcJwl8sI1v4PI2uYEPt4UbuLItxrCwoplgrMagaOZTENf2NK0NryE8gWRCVE3p6ae5j3aOFwyZb8of6RT3FYn7Y9yvmjlDx1mKGncSfVTC9Z/v6QyZE7q5rpsburmpm490U+K/12g6WXYc+nR4CKX/H31zGG1z5m9Pt5okCg==',
|
|
// moviePath: 'http://localhost:8000/tests/js/tests/Bookmarklet/ZeroClipboard.swf',
|
|
moviePath: 'http://www.clipperz.com/files/clipperz.com/bookmarklet/0.3.0/ZeroClipboard_1.0.4.swf',
|
|
nextId: 1, // ID of next movie
|
|
|
|
$: function(thingy) {
|
|
// simple DOM lookup utility function
|
|
if (typeof(thingy) == 'string') thingy = document.getElementById(thingy);
|
|
if (!thingy.addClass) {
|
|
// extend element with a few useful methods
|
|
thingy.hide = function() { this.style.display = 'none'; };
|
|
thingy.show = function() { this.style.display = ''; };
|
|
thingy.addClass = function(name) { this.removeClass(name); this.className += ' ' + name; };
|
|
thingy.removeClass = function(name) {
|
|
this.className = this.className.replace( new RegExp("\\s*" + name + "\\s*"), " ").replace(/^\s+/, '').replace(/\s+$/, '');
|
|
};
|
|
thingy.hasClass = function(name) {
|
|
return !!this.className.match( new RegExp("\\s*" + name + "\\s*") );
|
|
}
|
|
}
|
|
return thingy;
|
|
},
|
|
|
|
setMoviePath: function(path) {
|
|
// set path to ZeroClipboard.swf
|
|
this.moviePath = path;
|
|
},
|
|
|
|
dispatch: function(id, eventName, args) {
|
|
// receive event from flash movie, send to client
|
|
var client = this.clients[id];
|
|
if (client) {
|
|
client.receiveEvent(eventName, args);
|
|
}
|
|
},
|
|
|
|
register: function(id, client) {
|
|
// register new client to receive events
|
|
this.clients[id] = client;
|
|
},
|
|
|
|
getDOMObjectPosition: function(obj) {
|
|
// get absolute coordinates for dom element
|
|
var info = {
|
|
left: 0,
|
|
top: 0,
|
|
width: obj.width ? obj.width : obj.offsetWidth,
|
|
height: obj.height ? obj.height : obj.offsetHeight
|
|
};
|
|
|
|
while (obj) {
|
|
info.left += obj.offsetLeft;
|
|
info.top += obj.offsetTop;
|
|
obj = obj.offsetParent;
|
|
}
|
|
|
|
return info;
|
|
},
|
|
|
|
Client: function(elem) {
|
|
// constructor for new simple upload client
|
|
this.handlers = {};
|
|
|
|
// unique ID
|
|
this.id = ZeroClipboard.nextId++;
|
|
this.movieId = 'ZeroClipboardMovie_' + this.id;
|
|
|
|
// register client with singleton to receive flash events
|
|
ZeroClipboard.register(this.id, this);
|
|
|
|
// create movie
|
|
if (elem) this.glue(elem);
|
|
}
|
|
};
|
|
|
|
ZeroClipboard.Client.prototype = {
|
|
|
|
id: 0, // unique ID for us
|
|
ready: false, // whether movie is ready to receive events or not
|
|
movie: null, // reference to movie object
|
|
clipText: '', // text to copy to clipboard
|
|
handCursorEnabled: true, // whether to show hand cursor, or default pointer cursor
|
|
cssEffects: true, // enable CSS mouse effects on dom container
|
|
handlers: null, // user event handlers
|
|
|
|
glue: function(elem) {
|
|
// glue to DOM element
|
|
// elem can be ID or actual DOM element object
|
|
//console.log(">>> glue");
|
|
this.domElement = ZeroClipboard.$(elem);
|
|
|
|
// float just above object, or zIndex 99 if dom element isn't set
|
|
var zIndex = 99;
|
|
if (this.domElement.style.zIndex) {
|
|
zIndex = parseInt(this.domElement.style.zIndex) + 1;
|
|
}
|
|
|
|
// find X/Y position of domElement
|
|
var box = ZeroClipboard.getDOMObjectPosition(this.domElement);
|
|
|
|
// create floating DIV above element
|
|
this.div = document.createElement('div');
|
|
var style = this.div.style;
|
|
style.position = 'absolute';
|
|
style.left = '' + box.left + 'px';
|
|
style.top = '' + box.top + 'px';
|
|
style.width = '' + box.width + 'px';
|
|
style.height = '' + box.height + 'px';
|
|
style.zIndex = zIndex;
|
|
|
|
// style.backgroundColor = '#f00'; // debug
|
|
|
|
var body = document.getElementsByTagName('body')[0];
|
|
body.appendChild(this.div);
|
|
|
|
this.div.innerHTML = this.getHTML( box.width, box.height );
|
|
//console.log("<<< glue");
|
|
},
|
|
|
|
getHTML: function(width, height) {
|
|
// return HTML for movie
|
|
var html = '';
|
|
var flashvars = 'id=' + this.id +
|
|
'&width=' + width +
|
|
'&height=' + height;
|
|
|
|
if (navigator.userAgent.match(/MSIE/)) {
|
|
// IE gets an OBJECT tag
|
|
var protocol = location.href.match(/^https/i) ? 'https://' : 'http://';
|
|
html += '<object classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" codebase="'+protocol+'download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=9,0,0,0" width="'+width+'" height="'+height+'" id="'+this.movieId+'" align="middle"><param name="allowScriptAccess" value="always" /><param name="allowFullScreen" value="false" /><param name="movie" value="'+ZeroClipboard.moviePath+'" /><param name="loop" value="false" /><param name="menu" value="false" /><param name="quality" value="best" /><param name="bgcolor" value="#ffffff" /><param name="flashvars" value="'+flashvars+'"/><param name="wmode" value="transparent"/></object>';
|
|
}
|
|
else {
|
|
// all other browsers get an EMBED tag
|
|
html += '<embed id="'+this.movieId+'" src="'+ZeroClipboard.moviePath+'" loop="false" menu="false" quality="best" bgcolor="#ffffff" width="'+width+'" height="'+height+'" name="'+this.movieId+'" align="middle" allowScriptAccess="always" allowFullScreen="false" type="application/x-shockwave-flash" pluginspage="http://www.macromedia.com/go/getflashplayer" flashvars="'+flashvars+'" wmode="transparent" />';
|
|
}
|
|
return html;
|
|
},
|
|
|
|
hide: function() {
|
|
// temporarily hide floater offscreen
|
|
if (this.div) {
|
|
this.div.style.left = '-2000px';
|
|
}
|
|
},
|
|
|
|
show: function() {
|
|
// show ourselves after a call to hide()
|
|
this.reposition();
|
|
},
|
|
|
|
destroy: function() {
|
|
// destroy control and floater
|
|
if (this.domElement && this.div) {
|
|
this.hide();
|
|
this.div.innerHTML = '';
|
|
|
|
var body = document.getElementsByTagName('body')[0];
|
|
try { body.removeChild( this.div ); } catch(e) {;}
|
|
|
|
this.domElement = null;
|
|
this.div = null;
|
|
}
|
|
},
|
|
|
|
reposition: function(elem) {
|
|
// reposition our floating div, optionally to new container
|
|
// warning: container CANNOT change size, only position
|
|
if (elem) {
|
|
this.domElement = ZeroClipboard.$(elem);
|
|
if (!this.domElement) this.hide();
|
|
}
|
|
|
|
if (this.domElement && this.div) {
|
|
var box = ZeroClipboard.getDOMObjectPosition(this.domElement);
|
|
var style = this.div.style;
|
|
style.left = '' + box.left + 'px';
|
|
style.top = '' + box.top + 'px';
|
|
}
|
|
},
|
|
|
|
setText: function(newText) {
|
|
// set text to be copied to clipboard
|
|
this.clipText = newText;
|
|
if (this.ready) this.movie.setText(newText);
|
|
},
|
|
|
|
addEventListener: function(eventName, func) {
|
|
// add user event listener for event
|
|
// event types: load, queueStart, fileStart, fileComplete, queueComplete, progress, error, cancel
|
|
eventName = eventName.toString().toLowerCase().replace(/^on/, '');
|
|
if (!this.handlers[eventName]) this.handlers[eventName] = [];
|
|
this.handlers[eventName].push(func);
|
|
},
|
|
|
|
setHandCursor: function(enabled) {
|
|
// enable hand cursor (true), or default arrow cursor (false)
|
|
this.handCursorEnabled = enabled;
|
|
if (this.ready) this.movie.setHandCursor(enabled);
|
|
},
|
|
|
|
setCSSEffects: function(enabled) {
|
|
// enable or disable CSS effects on DOM container
|
|
this.cssEffects = !!enabled;
|
|
},
|
|
|
|
receiveEvent: function(eventName, args) {
|
|
// receive event from flash
|
|
eventName = eventName.toString().toLowerCase().replace(/^on/, '');
|
|
|
|
// special behavior for certain events
|
|
switch (eventName) {
|
|
case 'load':
|
|
// movie claims it is ready, but in IE this isn't always the case...
|
|
// bug fix: Cannot extend EMBED DOM elements in Firefox, must use traditional function
|
|
this.movie = document.getElementById(this.movieId);
|
|
if (!this.movie) {
|
|
var self = this;
|
|
setTimeout( function() { self.receiveEvent('load', null); }, 1 );
|
|
return;
|
|
}
|
|
|
|
// firefox on pc needs a "kick" in order to set these in certain cases
|
|
if (!this.ready && navigator.userAgent.match(/Firefox/) && navigator.userAgent.match(/Windows/)) {
|
|
var self = this;
|
|
setTimeout( function() { self.receiveEvent('load', null); }, 100 );
|
|
this.ready = true;
|
|
return;
|
|
}
|
|
|
|
this.ready = true;
|
|
this.movie.setText( this.clipText );
|
|
this.movie.setHandCursor( this.handCursorEnabled );
|
|
break;
|
|
|
|
case 'mouseover':
|
|
if (this.domElement && this.cssEffects) {
|
|
this.domElement.addClass('hover');
|
|
if (this.recoverActive) this.domElement.addClass('active');
|
|
}
|
|
break;
|
|
|
|
case 'mouseout':
|
|
if (this.domElement && this.cssEffects) {
|
|
this.recoverActive = false;
|
|
if (this.domElement.hasClass('active')) {
|
|
this.domElement.removeClass('active');
|
|
this.recoverActive = true;
|
|
}
|
|
this.domElement.removeClass('hover');
|
|
}
|
|
break;
|
|
|
|
case 'mousedown':
|
|
if (this.domElement && this.cssEffects) {
|
|
this.domElement.addClass('active');
|
|
}
|
|
break;
|
|
|
|
case 'mouseup':
|
|
if (this.domElement && this.cssEffects) {
|
|
this.domElement.removeClass('active');
|
|
this.recoverActive = false;
|
|
}
|
|
break;
|
|
} // switch eventName
|
|
|
|
if (this.handlers[eventName]) {
|
|
for (var idx = 0, len = this.handlers[eventName].length; idx < len; idx++) {
|
|
var func = this.handlers[eventName][idx];
|
|
|
|
if (typeof(func) == 'function') {
|
|
// actual function reference
|
|
func(this, args);
|
|
}
|
|
else if ((typeof(func) == 'object') && (func.length == 2)) {
|
|
// PHP style object + method, i.e. [myObject, 'myMethod']
|
|
func[0][ func[1] ](this, args);
|
|
}
|
|
else if (typeof(func) == 'string') {
|
|
// name of function
|
|
window[func](this, args);
|
|
}
|
|
} // foreach event handler defined
|
|
} // user defined handler for event
|
|
}
|
|
|
|
};
|
|
|
|
//#############################################################################
|
|
|
|
var clip = null;
|
|
|
|
function $(id) { return document.getElementById(id); }
|
|
|
|
function initClip() {
|
|
//console.log(">>> initClip");
|
|
clip = new ZeroClipboard.Client();
|
|
clip.setHandCursor( true );
|
|
|
|
// clip.addEventListener('load', my_load);
|
|
// clip.addEventListener('mouseOver', my_mouse_over);
|
|
clip.addEventListener('complete', my_complete);
|
|
|
|
// clip.glue( 'd_clip_button' );
|
|
//console.log("<<< initClip");
|
|
}
|
|
|
|
//function my_load(client) {
|
|
// console.log("Flash movie loaded and ready.");
|
|
//}
|
|
|
|
//function my_mouse_over(client) {
|
|
// // we can cheat a little here -- update the text on mouse over
|
|
// clip.setText( $('fe_text').value );
|
|
//}
|
|
|
|
function my_complete(client, text) {
|
|
// console.log("Copied text to clipboard: ... ");
|
|
// console.log("Copied text to clipboard: " + text );
|
|
clipperz_copiedContentToClipboard = true;
|
|
showTooltip();
|
|
}
|
|
|
|
//function debugstr(msg) {
|
|
// var p = document.createElement('p');
|
|
// p.innerHTML = msg;
|
|
// $('d_debug').appendChild(p);
|
|
//}
|
|
|
|
//#############################################################################
|
|
|
|
_cble = null;
|
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
isLoginForm = function(aForm) {
|
|
var inputFields;
|
|
var passwordFieldsFound;
|
|
var i,c;
|
|
|
|
//console.log("is login form: " + aForm.name + " (" + aForm.id + ")");
|
|
passwordFieldsFound = 0;
|
|
inputFields = aForm.elements;
|
|
c = inputFields.length;
|
|
for (i=0; i<c; i++) {
|
|
if (inputFields[i].type == "password") {
|
|
passwordFieldsFound ++;
|
|
}
|
|
}
|
|
//console.log("number of password fields found: " + passwordFieldsFound);
|
|
return (passwordFieldsFound == 1);
|
|
};
|
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
findLoginForm = function(aDocument, aLevel) {
|
|
var result;
|
|
var documentForms;
|
|
var i,c;
|
|
|
|
result = null;
|
|
|
|
try {
|
|
documentForms = aDocument.getElementsByTagName('form');
|
|
|
|
c = documentForms.length;
|
|
for (i=0; (i<c) && (result == null); i++) {
|
|
if (isLoginForm(documentForms[i])) {
|
|
result = documentForms[i];
|
|
}
|
|
}
|
|
|
|
if ((result == null) && (aLevel == 0)) {
|
|
var iFrames;
|
|
|
|
iFrames = aDocument.getElementsByTagName('iframe');
|
|
c = iFrames.length;
|
|
for (i=0; (i<c) && (result == null); i++) {
|
|
result = findLoginForm(iFrames[i].contentDocument, (aLevel + 1));
|
|
}
|
|
}
|
|
} catch (e) {
|
|
_cble = e;
|
|
}
|
|
|
|
return result;
|
|
};
|
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
inputElementValues = function(anInputElement) {
|
|
var result;
|
|
|
|
// if ((anInputElement instanceof HTMLInputElement) && (anInputElement.getAttribute('name') != null)) {
|
|
if ((anInputElement.tagName.toLowerCase() == "input") && (anInputElement.getAttribute('name') != null)) {
|
|
result = {};
|
|
result.type = anInputElement.getAttribute('type') || "text";
|
|
result.name = anInputElement.getAttribute('name');
|
|
// result.value = anInputElement.getAttribute('value');
|
|
result.value = anInputElement.value;
|
|
if (anInputElement.type.toLowerCase() == 'radio') {
|
|
result.checked = anInputElement.checked;
|
|
}
|
|
// } else if ((anInputElement instanceof HTMLSelectElement) && (anInputElement.getAttribute('name') != null)) {
|
|
} else if ((anInputElement.tagName.toLowerCase() == 'select') && (anInputElement.getAttribute('name') != null)) {
|
|
var options;
|
|
var c,i;
|
|
|
|
//console.log("input element values: %o", anInputElement);
|
|
result = {};
|
|
result.type = "select";
|
|
result.name = anInputElement.getAttribute('name');
|
|
|
|
result.options = [];
|
|
options = anInputElement.options;
|
|
c = options.length;
|
|
for (i=0; i<c; i++) {
|
|
var option;
|
|
|
|
option = {};
|
|
option.selected = options[i].selected;
|
|
option.label = options[i].label || options[i].innerHTML;
|
|
option.value = options[i].value;
|
|
result.options.push(option);
|
|
}
|
|
} else {
|
|
result = null;
|
|
}
|
|
|
|
return result;
|
|
};
|
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
formParameters = function(aLoginForm) {
|
|
var result;
|
|
var i, c;
|
|
var action;
|
|
|
|
if (aLoginForm == null) {
|
|
result = null;
|
|
} else {
|
|
var radioValues;
|
|
var radioValueName;
|
|
|
|
result = {};
|
|
radioValues = {};
|
|
|
|
action = aLoginForm.action;
|
|
if (action.constructor != String) {
|
|
action = aLoginForm.getAttribute('action');
|
|
}
|
|
|
|
if (/^https?\:\/\/.*/.test(action)) {
|
|
action = action;
|
|
} else if (/^\/.*/.test(action)) {
|
|
action = window.location.protocol + '/' + '/' + window.location.hostname + action;
|
|
} else {
|
|
action = window.location.href.replace(/\/[^\/]*$/, '/' + action);
|
|
}
|
|
|
|
result.attributes = {};
|
|
result.attributes.action = action;
|
|
result.attributes.method = aLoginForm.getAttribute('method');
|
|
|
|
result.inputs = [];
|
|
c = aLoginForm.elements.length;
|
|
for (i=0; i<c; i++) {
|
|
var inputElement;
|
|
var elementValues;
|
|
|
|
inputElement = aLoginForm.elements[i];
|
|
elementValues = inputElementValues(inputElement);
|
|
if (elementValues != null) {
|
|
if (elementValues.type != "radio") {
|
|
result.inputs.push(elementValues);
|
|
} else {
|
|
var radioValue;
|
|
var values;
|
|
|
|
radioValue = radioValues[elementValues.name];
|
|
if (radioValue == null) {
|
|
radioValue = {};
|
|
radioValue.name = elementValues.name;
|
|
radioValue.type = "radio";
|
|
radioValue.options = [];
|
|
|
|
radioValues[elementValues.name] = radioValue;
|
|
}
|
|
|
|
values = {};
|
|
values.value = elementValues.value;
|
|
values.checked = elementValues.checked;
|
|
|
|
radioValue.options.push(values);
|
|
}
|
|
}
|
|
}
|
|
|
|
for (radioValueName in radioValues) {
|
|
if (typeof(radioValues[radioValueName]) != "function") {
|
|
result.inputs.push(radioValues[radioValueName]);
|
|
}
|
|
}
|
|
}
|
|
|
|
return result;
|
|
};
|
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
pageParameters = function() {
|
|
var result;
|
|
|
|
result = {};
|
|
result['title'] = document.title;
|
|
//<link rel="icon" href="http://example.com/favicon.ico" type="image/x-icon">
|
|
|
|
return result;
|
|
};
|
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
reprString = function (o) {
|
|
return ('"' + o.replace(/(["\\])/g, '\\$1') + '"'
|
|
).replace(/[\f]/g, "\\f"
|
|
).replace(/[\b]/g, "\\b"
|
|
).replace(/[\n]/g, "\\n"
|
|
).replace(/[\t]/g, "\\t"
|
|
).replace(/[\r]/g, "\\r");
|
|
};
|
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
serializeJSON = function (o) {
|
|
var objtype = typeof(o);
|
|
if (objtype == "number" || objtype == "boolean") {
|
|
return o + "";
|
|
} else if (o === null) {
|
|
return "null";
|
|
}
|
|
|
|
// var m = MochiKit.Base;
|
|
// var reprString = m.reprString;
|
|
if (objtype == "string") {
|
|
return reprString(o);
|
|
}
|
|
|
|
// recurse
|
|
var me = arguments.callee;
|
|
// array
|
|
if (objtype != "function" && typeof(o.length) == "number") {
|
|
var res = [];
|
|
for (var i = 0; i < o.length; i++) {
|
|
var val = me(o[i]);
|
|
if (typeof(val) != "string") {
|
|
val = "undefined";
|
|
}
|
|
res.push(val);
|
|
}
|
|
return "[" + res.join(",\n") + "]";
|
|
}
|
|
|
|
// undefined is outside of the spec
|
|
if (objtype == "undefined") {
|
|
// throw new TypeError("undefined can not be serialized as JSON");
|
|
throw new TypeError("error");
|
|
}
|
|
|
|
// generic object code path
|
|
res = [];
|
|
for (var k in o) {
|
|
if (typeof(o[k]) != "function") {
|
|
var useKey;
|
|
if (typeof(k) == "number") {
|
|
useKey = '"' + k + '"';
|
|
} else if (typeof(k) == "string") {
|
|
useKey = reprString(k);
|
|
} else {
|
|
// skip non-string or number keys
|
|
continue;
|
|
}
|
|
|
|
val = me(o[k]);
|
|
if (typeof(val) != "string") {
|
|
// skip non-serializable values
|
|
continue;
|
|
}
|
|
res.push(useKey + ":" + " " + val);
|
|
}
|
|
}
|
|
|
|
return "{" + res.join(",\n") + "}";
|
|
};
|
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
getLoginFormConfiguration = function() {
|
|
var parameters;
|
|
|
|
parameters = {};
|
|
parameters.page = pageParameters();
|
|
parameters.form = formParameters(findLoginForm(document, 0));
|
|
parameters.version = "0.3.0";
|
|
|
|
return parameters;
|
|
}
|
|
|
|
//#############################################################################
|
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
closeClick = function () {
|
|
var bookmarkletDiv;
|
|
|
|
bookmarkletDiv = document.getElementById("clipperzBookmarkletWrapper");
|
|
bookmarkletDiv.parentNode.removeChild(bookmarkletDiv);
|
|
};
|
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
logFormParameters = function(someParameters, anException) {
|
|
var showException;
|
|
var message;
|
|
|
|
if ((someParameters != null) && (someParameters.form != null) && (anException == null)) {
|
|
showException = false;
|
|
message = "The direct login configuration has been collected.";
|
|
} else {
|
|
showException = true
|
|
message = "Sorry! There was an error while processing the page.";
|
|
}
|
|
|
|
var newCSS = document.createElement('link');
|
|
newCSS.setAttribute("type", "text/css");
|
|
newCSS.setAttribute("rel", "stylesheet");
|
|
newCSS.setAttribute("media", "screen");
|
|
newCSS.setAttribute("href", "http://www.clipperz.com/files/clipperz.com/bookmarklet/0.3.0/Bookmarklet.css");
|
|
// newCSS.innerHTML = cssHTML;
|
|
document.getElementsByTagName("head")[0].appendChild(newCSS);
|
|
|
|
var innerHTML;
|
|
|
|
innerHTML = "";
|
|
// innerHTML += "<div id='clipperzBookmarklet' style='" + reset_css + clipperzBookmarklet_style + "'>" +
|
|
// "<div id='clipperzBookmarkletClose' style='" + reset_css + clipperzBookmarkletClose_style + "'></div>" +
|
|
// "<div id='clipperzBookmarkletResult' style='" + reset_css + clipperzBookmarkletResult_style + "'>" +
|
|
// "<div id='clipperzBookmarkletResultIcon' style='" + reset_css + clipperzBookmarkletResultIcon_style + "'></div>" +
|
|
// "<p id='clipperzBookmarkletResultText' style='" + reset_css + clipperzBookmarkletResultText_style + "'>" + message + "</p>" +
|
|
// "</div>";
|
|
//
|
|
// if (showException == false) {
|
|
// innerHTML +="<div id='clipperzBookmarletButton' style='" + clipperzBookmarletButton_style + "'></div>" +
|
|
// "<div id='clipperzBookmarletAfterCopyHint' style='" + clipperzBookmarletAfterCopyHint_style + "'>" +
|
|
// "<p id='clipperzBookmarkletHintText' style='" + clipperzBookmarkletHintText_style + "'></p>" +
|
|
// "</div>";
|
|
// }
|
|
|
|
innerHTML += "<div id='clipperzBookmarklet'>" +
|
|
"<div id='clipperzBookmarkletClose'></div>" +
|
|
"<div id='clipperzBookmarkletResult'>" +
|
|
"<div id='clipperzBookmarkletResultIcon'></div>" +
|
|
"<p id='clipperzBookmarkletResultText'>" + message + "</p>" +
|
|
"</div>";
|
|
|
|
if (showException == false) {
|
|
innerHTML += "<div id='clipperzBookmarletButton'></div>" +
|
|
"<div id='clipperzBookmarletAfterCopyHint' class='hidden'>" +
|
|
"<p id='clipperzBookmarkletHintText'>Lorem ipsum</p>" +
|
|
"</div>";
|
|
}
|
|
|
|
innerHTML += "</div>";
|
|
|
|
var newDiv = document.createElement('div');
|
|
newDiv.setAttribute("id", "clipperzBookmarkletWrapper");
|
|
newDiv.innerHTML = innerHTML;
|
|
document.body.appendChild(newDiv);
|
|
|
|
$('clipperzBookmarkletClose').onclick = closeClick;
|
|
|
|
if (showException == false) {
|
|
$('clipperzBookmarletButton').onclick = showTooltip;
|
|
setTimeout("clip.glue('clipperzBookmarletButton');", 1000);
|
|
}
|
|
}
|
|
|
|
showTooltip = function () {
|
|
if (clipperz_copiedContentToClipboard == true) {
|
|
//console.log("SUCCEED");
|
|
$('clipperzBookmarkletHintText').innerHTML = "DONE!";
|
|
$('clipperzBookmarletAfterCopyHint').className = 'visible';
|
|
} else {
|
|
//console.log("FAIL");
|
|
$('clipperzBookmarkletHintText').innerHTML = "Failed! :(";
|
|
}
|
|
}
|
|
|
|
//#############################################################################
|
|
|
|
//#############################################################################
|
|
|
|
runBookmarklet = function () {
|
|
var parameters;
|
|
|
|
try {
|
|
initClip();
|
|
|
|
parameters = getLoginFormConfiguration();
|
|
//console.log("configuration", serializeJSON(parameters))
|
|
clip.setText(serializeJSON(parameters));
|
|
// clip.glue('clipperzBookmarletButton');
|
|
|
|
logFormParameters(parameters, _cble);
|
|
} catch (e) {
|
|
logFormParameters(parameters, e);
|
|
}
|
|
|
|
}
|
|
|
|
//#############################################################################
|
|
|
|
if (document.body != null) {
|
|
runBookmarklet();
|
|
}
|
|
|
|
//#############################################################################
|