* avatar, username, city from Google profile
* refactoring
This commit is contained in:
parent
edd160ae75
commit
c7f81699a4
55 changed files with 706 additions and 351 deletions
120
web/Scripts/jquery.metadata.js
Normal file
120
web/Scripts/jquery.metadata.js
Normal file
|
|
@ -0,0 +1,120 @@
|
|||
/*
|
||||
* Metadata - jQuery plugin for parsing metadata from elements
|
||||
*
|
||||
* Copyright (c) 2006 John Resig, Yehuda Katz, Jörn Zaefferer, Paul McLanahan
|
||||
*
|
||||
* Dual licensed under the MIT and GPL licenses:
|
||||
* http://www.opensource.org/licenses/mit-license.php
|
||||
* http://www.gnu.org/licenses/gpl.html
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* Sets the type of metadata to use. Metadata is encoded in JSON, and each property
|
||||
* in the JSON will become a property of the element itself.
|
||||
*
|
||||
* There are three supported types of metadata storage:
|
||||
*
|
||||
* attr: Inside an attribute. The name parameter indicates *which* attribute.
|
||||
*
|
||||
* class: Inside the class attribute, wrapped in curly braces: { }
|
||||
*
|
||||
* elem: Inside a child element (e.g. a script tag). The
|
||||
* name parameter indicates *which* element.
|
||||
*
|
||||
* The metadata for an element is loaded the first time the element is accessed via jQuery.
|
||||
*
|
||||
* As a result, you can define the metadata type, use $(expr) to load the metadata into the elements
|
||||
* matched by expr, then redefine the metadata type and run another $(expr) for other elements.
|
||||
*
|
||||
* @name $.metadata.setType
|
||||
*
|
||||
* @example <p id="one" class="some_class {item_id: 1, item_label: 'Label'}">This is a p</p>
|
||||
* @before $.metadata.setType("class")
|
||||
* @after $("#one").metadata().item_id == 1; $("#one").metadata().item_label == "Label"
|
||||
* @desc Reads metadata from the class attribute
|
||||
*
|
||||
* @example <p id="one" class="some_class" data="{item_id: 1, item_label: 'Label'}">This is a p</p>
|
||||
* @before $.metadata.setType("attr", "data")
|
||||
* @after $("#one").metadata().item_id == 1; $("#one").metadata().item_label == "Label"
|
||||
* @desc Reads metadata from a "data" attribute
|
||||
*
|
||||
* @example <p id="one" class="some_class"><script>{item_id: 1, item_label: 'Label'}</script>This is a p</p>
|
||||
* @before $.metadata.setType("elem", "script")
|
||||
* @after $("#one").metadata().item_id == 1; $("#one").metadata().item_label == "Label"
|
||||
* @desc Reads metadata from a nested script element
|
||||
*
|
||||
* @param String type The encoding type
|
||||
* @param String name The name of the attribute to be used to get metadata (optional)
|
||||
* @cat Plugins/Metadata
|
||||
* @descr Sets the type of encoding to be used when loading metadata for the first time
|
||||
* @type undefined
|
||||
* @see metadata()
|
||||
*/
|
||||
|
||||
(function($) {
|
||||
|
||||
$.extend({
|
||||
metadata : {
|
||||
defaults : {
|
||||
type: 'class',
|
||||
name: 'metadata',
|
||||
cre: /({.*})/,
|
||||
single: 'metadata'
|
||||
},
|
||||
setType: function( type, name ){
|
||||
this.defaults.type = type;
|
||||
this.defaults.name = name;
|
||||
},
|
||||
get: function( elem, opts ){
|
||||
var settings = $.extend({},this.defaults,opts);
|
||||
// check for empty string in single property
|
||||
if ( !settings.single.length ) settings.single = 'metadata';
|
||||
|
||||
var data = $.data(elem, settings.single);
|
||||
// returned cached data if it already exists
|
||||
if ( data ) return data;
|
||||
|
||||
data = "{}";
|
||||
|
||||
if ( settings.type == "class" ) {
|
||||
var m = settings.cre.exec( elem.className );
|
||||
if ( m )
|
||||
data = m[1];
|
||||
} else if ( settings.type == "elem" ) {
|
||||
if( !elem.getElementsByTagName )
|
||||
return undefined;
|
||||
var e = elem.getElementsByTagName(settings.name);
|
||||
if ( e.length )
|
||||
data = $.trim(e[0].innerHTML);
|
||||
} else if ( elem.getAttribute != undefined ) {
|
||||
var attr = elem.getAttribute( settings.name );
|
||||
if ( attr )
|
||||
data = attr;
|
||||
}
|
||||
|
||||
if ( data.indexOf( '{' ) <0 )
|
||||
data = "{" + data + "}";
|
||||
|
||||
data = eval("(" + data + ")");
|
||||
|
||||
$.data( elem, settings.single, data );
|
||||
return data;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* Returns the metadata object for the first member of the jQuery object.
|
||||
*
|
||||
* @name metadata
|
||||
* @descr Returns element's metadata object
|
||||
* @param Object opts An object contianing settings to override the defaults
|
||||
* @type jQuery
|
||||
* @cat Plugins/Metadata
|
||||
*/
|
||||
$.fn.metadata = function( opts ){
|
||||
return $.metadata.get( this[0], opts );
|
||||
};
|
||||
|
||||
})(jQuery);
|
||||
1031
web/Scripts/jquery.tablesorter.js
Normal file
1031
web/Scripts/jquery.tablesorter.js
Normal file
File diff suppressed because it is too large
Load diff
4
web/Scripts/jquery.tablesorter.min.js
vendored
Normal file
4
web/Scripts/jquery.tablesorter.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
274
web/Scripts/rangyinputs-jquery-1.1.2.js
Normal file
274
web/Scripts/rangyinputs-jquery-1.1.2.js
Normal file
|
|
@ -0,0 +1,274 @@
|
|||
/**
|
||||
* @license Rangy Inputs, a jQuery plug-in for selection and caret manipulation within textareas and text inputs.
|
||||
*
|
||||
* https://github.com/timdown/rangyinputs
|
||||
*
|
||||
* For range and selection features for contenteditable, see Rangy.
|
||||
|
||||
* http://code.google.com/p/rangy/
|
||||
*
|
||||
* Depends on jQuery 1.0 or later.
|
||||
*
|
||||
* Copyright 2013, Tim Down
|
||||
* Licensed under the MIT license.
|
||||
* Version: 1.1.2
|
||||
* Build date: 6 September 2013
|
||||
*/
|
||||
(function($) {
|
||||
var UNDEF = "undefined";
|
||||
var getSelection, setSelection, deleteSelectedText, deleteText, insertText;
|
||||
var replaceSelectedText, surroundSelectedText, extractSelectedText, collapseSelection;
|
||||
|
||||
// Trio of isHost* functions taken from Peter Michaux's article:
|
||||
// http://peter.michaux.ca/articles/feature-detection-state-of-the-art-browser-scripting
|
||||
function isHostMethod(object, property) {
|
||||
var t = typeof object[property];
|
||||
return t === "function" || (!!(t == "object" && object[property])) || t == "unknown";
|
||||
}
|
||||
|
||||
function isHostProperty(object, property) {
|
||||
return typeof(object[property]) != UNDEF;
|
||||
}
|
||||
|
||||
function isHostObject(object, property) {
|
||||
return !!(typeof(object[property]) == "object" && object[property]);
|
||||
}
|
||||
|
||||
function fail(reason) {
|
||||
if (window.console && window.console.log) {
|
||||
window.console.log("RangyInputs not supported in your browser. Reason: " + reason);
|
||||
}
|
||||
}
|
||||
|
||||
function adjustOffsets(el, start, end) {
|
||||
if (start < 0) {
|
||||
start += el.value.length;
|
||||
}
|
||||
if (typeof end == UNDEF) {
|
||||
end = start;
|
||||
}
|
||||
if (end < 0) {
|
||||
end += el.value.length;
|
||||
}
|
||||
return { start: start, end: end };
|
||||
}
|
||||
|
||||
function makeSelection(el, start, end) {
|
||||
return {
|
||||
start: start,
|
||||
end: end,
|
||||
length: end - start,
|
||||
text: el.value.slice(start, end)
|
||||
};
|
||||
}
|
||||
|
||||
function getBody() {
|
||||
return isHostObject(document, "body") ? document.body : document.getElementsByTagName("body")[0];
|
||||
}
|
||||
|
||||
$(document).ready(function() {
|
||||
var testTextArea = document.createElement("textarea");
|
||||
|
||||
getBody().appendChild(testTextArea);
|
||||
|
||||
if (isHostProperty(testTextArea, "selectionStart") && isHostProperty(testTextArea, "selectionEnd")) {
|
||||
getSelection = function(el) {
|
||||
var start = el.selectionStart, end = el.selectionEnd;
|
||||
return makeSelection(el, start, end);
|
||||
};
|
||||
|
||||
setSelection = function(el, startOffset, endOffset) {
|
||||
var offsets = adjustOffsets(el, startOffset, endOffset);
|
||||
el.selectionStart = offsets.start;
|
||||
el.selectionEnd = offsets.end;
|
||||
};
|
||||
|
||||
collapseSelection = function(el, toStart) {
|
||||
if (toStart) {
|
||||
el.selectionEnd = el.selectionStart;
|
||||
} else {
|
||||
el.selectionStart = el.selectionEnd;
|
||||
}
|
||||
};
|
||||
} else if (isHostMethod(testTextArea, "createTextRange") && isHostObject(document, "selection") &&
|
||||
isHostMethod(document.selection, "createRange")) {
|
||||
|
||||
getSelection = function(el) {
|
||||
var start = 0, end = 0, normalizedValue, textInputRange, len, endRange;
|
||||
var range = document.selection.createRange();
|
||||
|
||||
if (range && range.parentElement() == el) {
|
||||
len = el.value.length;
|
||||
|
||||
normalizedValue = el.value.replace(/\r\n/g, "\n");
|
||||
textInputRange = el.createTextRange();
|
||||
textInputRange.moveToBookmark(range.getBookmark());
|
||||
endRange = el.createTextRange();
|
||||
endRange.collapse(false);
|
||||
if (textInputRange.compareEndPoints("StartToEnd", endRange) > -1) {
|
||||
start = end = len;
|
||||
} else {
|
||||
start = -textInputRange.moveStart("character", -len);
|
||||
start += normalizedValue.slice(0, start).split("\n").length - 1;
|
||||
if (textInputRange.compareEndPoints("EndToEnd", endRange) > -1) {
|
||||
end = len;
|
||||
} else {
|
||||
end = -textInputRange.moveEnd("character", -len);
|
||||
end += normalizedValue.slice(0, end).split("\n").length - 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return makeSelection(el, start, end);
|
||||
};
|
||||
|
||||
// Moving across a line break only counts as moving one character in a TextRange, whereas a line break in
|
||||
// the textarea value is two characters. This function corrects for that by converting a text offset into a
|
||||
// range character offset by subtracting one character for every line break in the textarea prior to the
|
||||
// offset
|
||||
var offsetToRangeCharacterMove = function(el, offset) {
|
||||
return offset - (el.value.slice(0, offset).split("\r\n").length - 1);
|
||||
};
|
||||
|
||||
setSelection = function(el, startOffset, endOffset) {
|
||||
var offsets = adjustOffsets(el, startOffset, endOffset);
|
||||
var range = el.createTextRange();
|
||||
var startCharMove = offsetToRangeCharacterMove(el, offsets.start);
|
||||
range.collapse(true);
|
||||
if (offsets.start == offsets.end) {
|
||||
range.move("character", startCharMove);
|
||||
} else {
|
||||
range.moveEnd("character", offsetToRangeCharacterMove(el, offsets.end));
|
||||
range.moveStart("character", startCharMove);
|
||||
}
|
||||
range.select();
|
||||
};
|
||||
|
||||
collapseSelection = function(el, toStart) {
|
||||
var range = document.selection.createRange();
|
||||
range.collapse(toStart);
|
||||
range.select();
|
||||
};
|
||||
} else {
|
||||
getBody().removeChild(testTextArea);
|
||||
fail("No means of finding text input caret position");
|
||||
return;
|
||||
}
|
||||
|
||||
// Clean up
|
||||
getBody().removeChild(testTextArea);
|
||||
|
||||
deleteText = function(el, start, end, moveSelection) {
|
||||
var val;
|
||||
if (start != end) {
|
||||
val = el.value;
|
||||
el.value = val.slice(0, start) + val.slice(end);
|
||||
}
|
||||
if (moveSelection) {
|
||||
setSelection(el, start, start);
|
||||
}
|
||||
};
|
||||
|
||||
deleteSelectedText = function(el) {
|
||||
var sel = getSelection(el);
|
||||
deleteText(el, sel.start, sel.end, true);
|
||||
};
|
||||
|
||||
extractSelectedText = function(el) {
|
||||
var sel = getSelection(el), val;
|
||||
if (sel.start != sel.end) {
|
||||
val = el.value;
|
||||
el.value = val.slice(0, sel.start) + val.slice(sel.end);
|
||||
}
|
||||
setSelection(el, sel.start, sel.start);
|
||||
return sel.text;
|
||||
};
|
||||
|
||||
var updateSelectionAfterInsert = function(el, startIndex, text, selectionBehaviour) {
|
||||
var endIndex = startIndex + text.length;
|
||||
|
||||
selectionBehaviour = (typeof selectionBehaviour == "string") ?
|
||||
selectionBehaviour.toLowerCase() : "";
|
||||
|
||||
if ((selectionBehaviour == "collapsetoend" || selectionBehaviour == "select") && /[\r\n]/.test(text)) {
|
||||
// Find the length of the actual text inserted, which could vary
|
||||
// depending on how the browser deals with line breaks
|
||||
var normalizedText = text.replace(/\r\n/g, "\n").replace(/\r/g, "\n");
|
||||
endIndex = startIndex + normalizedText.length;
|
||||
var firstLineBreakIndex = startIndex + normalizedText.indexOf("\n");
|
||||
|
||||
if (el.value.slice(firstLineBreakIndex, firstLineBreakIndex + 2) == "\r\n") {
|
||||
// Browser uses \r\n, so we need to account for extra \r characters
|
||||
endIndex += normalizedText.match(/\n/g).length;
|
||||
}
|
||||
}
|
||||
|
||||
switch (selectionBehaviour) {
|
||||
case "collapsetostart":
|
||||
setSelection(el, startIndex, startIndex);
|
||||
break;
|
||||
case "collapsetoend":
|
||||
setSelection(el, endIndex, endIndex);
|
||||
break;
|
||||
case "select":
|
||||
setSelection(el, startIndex, endIndex);
|
||||
break;
|
||||
}
|
||||
};
|
||||
|
||||
insertText = function(el, text, index, selectionBehaviour) {
|
||||
var val = el.value;
|
||||
el.value = val.slice(0, index) + text + val.slice(index);
|
||||
if (typeof selectionBehaviour == "boolean") {
|
||||
selectionBehaviour = selectionBehaviour ? "collapseToEnd" : "";
|
||||
}
|
||||
updateSelectionAfterInsert(el, index, text, selectionBehaviour);
|
||||
};
|
||||
|
||||
replaceSelectedText = function(el, text, selectionBehaviour) {
|
||||
var sel = getSelection(el), val = el.value;
|
||||
el.value = val.slice(0, sel.start) + text + val.slice(sel.end);
|
||||
updateSelectionAfterInsert(el, sel.start, text, selectionBehaviour || "collapseToEnd");
|
||||
};
|
||||
|
||||
surroundSelectedText = function(el, before, after, selectionBehaviour) {
|
||||
if (typeof after == UNDEF) {
|
||||
after = before;
|
||||
}
|
||||
var sel = getSelection(el), val = el.value;
|
||||
el.value = val.slice(0, sel.start) + before + sel.text + after + val.slice(sel.end);
|
||||
var startIndex = sel.start + before.length;
|
||||
updateSelectionAfterInsert(el, startIndex, sel.text, selectionBehaviour || "select");
|
||||
};
|
||||
|
||||
function jQuerify(func, returnThis) {
|
||||
return function() {
|
||||
var el = this.jquery ? this[0] : this;
|
||||
var nodeName = el.nodeName.toLowerCase();
|
||||
|
||||
if (el.nodeType == 1 && (nodeName == "textarea" || (nodeName == "input" && el.type == "text"))) {
|
||||
var args = [el].concat(Array.prototype.slice.call(arguments));
|
||||
var result = func.apply(this, args);
|
||||
if (!returnThis) {
|
||||
return result;
|
||||
}
|
||||
}
|
||||
if (returnThis) {
|
||||
return this;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
$.fn.extend({
|
||||
getSelection: jQuerify(getSelection, false),
|
||||
setSelection: jQuerify(setSelection, true),
|
||||
collapseSelection: jQuerify(collapseSelection, true),
|
||||
deleteSelectedText: jQuerify(deleteSelectedText, true),
|
||||
deleteText: jQuerify(deleteText, true),
|
||||
extractSelectedText: jQuerify(extractSelectedText, false),
|
||||
insertText: jQuerify(insertText, true),
|
||||
replaceSelectedText: jQuerify(replaceSelectedText, true),
|
||||
surroundSelectedText: jQuerify(surroundSelectedText, true)
|
||||
});
|
||||
});
|
||||
})(jQuery);
|
||||
Loading…
Add table
Add a link
Reference in a new issue