first commit

This commit is contained in:
alazhar
2020-01-02 23:15:16 +07:00
commit eda9661806
3433 changed files with 595883 additions and 0 deletions

View File

@ -0,0 +1,900 @@
var UniteAdminRev = new function(){
var t = this;
var errorMessageID = null;
var successMessageID = null;
var ajaxLoaderID = null;
var ajaxHideButtonID = null;
//video dialog vars:
var lastVideoData = null; //last fetched data
var lastVideoCallback = null; //last callback from video dialog return
var colorPickerCallback = null;
/**
* escape html, turn html to a string
*/
t.htmlspecialchars = function(string){
return string
.replace(/&/g, "&")
.replace(/</g, "&lt;")
.replace(/>/g, "&gt;")
.replace(/"/g, "&quot;")
.replace(/'/g, "&#039;");
}
/**
* turn string value ("true", "false") to string
*/
t.strToBool = function(str){
if(str == undefined)
return(false);
if(typeof(str) != "string")
return(false);
str = str.toLowerCase();
var bool = (str == "true")?true:false;
return(bool);
}
/**
* set callback on color picker movement
*/
t.setColorPickerCallback = function(callbackFunc){
colorPickerCallback = callbackFunc;
}
/**
* on color picker event. Pass the event further
*/
t.onColorPickerMoveEvent = function(event){
if(typeof colorPickerCallback == "function")
colorPickerCallback(event);
}
/**
* strip html tags
*/
t.stripTags = function(input, allowed) {
allowed = (((allowed || "") + "").toLowerCase().match(/<[a-z][a-z0-9]*>/g) || []).join(''); // making sure the allowed arg is a string containing only tags in lowercase (<a><b><c>)
var tags = /<\/?([a-z][a-z0-9]*)\b[^>]*>/gi,
commentsAndPhpTags = /<!--[\s\S]*?-->|<\?(?:php)?[\s\S]*?\?>/gi;
return input.replace(commentsAndPhpTags, '').replace(tags, function ($0, $1) {
return allowed.indexOf('<' + $1.toLowerCase() + '>') > -1 ? $0 : '';
});
}
/**
* debug html on the top of the page (from the master view)
*/
t.debug = function(html){
jQuery("#div_debug").show().html(html);
}
/**
* output data to console
*/
t.trace = function(data,clear){
if(clear && clear == true)
console.clear();
console.log(data);
}
/**
* show error message or call once custom handler function
*/
t.showErrorMessage = function(htmlError){
if(errorMessageID !== null){
jQuery("#"+errorMessageID).show().html(htmlError);
}else
jQuery("#error_message").show().html(htmlError);
showAjaxButton();
}
/**
* hide error message
*/
var hideErrorMessage = function(){
if(errorMessageID !== null){
jQuery("#"+errorMessageID).hide();
errorMessageID = null;
}else
jQuery("#error_message").hide();
}
/**
* set error message id
*/
t.setErrorMessageID = function(id){
errorMessageID = id;
}
/**
* set success message id
*/
t.setSuccessMessageID = function(id){
successMessageID = id;
}
/**
* show success message
*/
var showSuccessMessage = function(htmlSuccess){
var id = "#success_message";
var delay = 2000;
if(successMessageID){
id = "#"+successMessageID;
delay = 500;
}
jQuery(id).show().html(htmlSuccess);
setTimeout("UniteAdminRev.hideSuccessMessage()",delay);
}
/**
* hide success message
*/
this.hideSuccessMessage = function(){
if(successMessageID){
jQuery("#"+successMessageID).hide();
successMessageID = null; //can be used only once.
}
else
jQuery("#success_message").slideUp("slow").fadeOut("slow");
showAjaxButton();
}
/**
* set ajax loader id that will be shown, and hidden on ajax request
* this loader will be shown only once, and then need to be sent again.
*/
this.setAjaxLoaderID = function(id){
ajaxLoaderID = id;
}
/**
* show loader on ajax actions
*/
var showAjaxLoader = function(){
if(ajaxLoaderID)
jQuery("#"+ajaxLoaderID).show();
}
/**
* hide and remove ajax loader. next time has to be set again before "ajaxRequest" function.
*/
var hideAjaxLoader = function(){
if(ajaxLoaderID){
jQuery("#"+ajaxLoaderID).hide();
ajaxLoaderID = null;
}
}
/**
* set button to hide / show on ajax operations.
*/
this.setAjaxHideButtonID = function(buttonID){
ajaxHideButtonID = buttonID;
}
/**
* if exist ajax button to hide, hide it.
*/
var hideAjaxButton = function(){
if(ajaxHideButtonID)
jQuery("#"+ajaxHideButtonID).hide();
}
/**
* if exist ajax button, show it, and remove the button id.
*/
var showAjaxButton = function(){
if(ajaxHideButtonID){
jQuery("#"+ajaxHideButtonID).show();
ajaxHideButtonID = null;
}
}
/**
* Ajax request function. call wp ajax, if error - print error message.
* if success, call "success function"
*/
t.ajaxRequest = function(action,data,successFunction){
var objData = {
action:g_uniteDirPlagin+"_ajax_action",
client_action:action,
data:data
}
hideErrorMessage();
showAjaxLoader();
hideAjaxButton();
jQuery.ajax({
type:"post",
url:ajaxurl,
dataType: 'json',
data:objData,
success:function(response){
hideAjaxLoader();
if(!response){
t.showErrorMessage("Empty ajax response!");
return(false);
}
if(response == -1){
t.showErrorMessage("ajax error!!!");
return(false);
}
if(response == 0){
t.showErrorMessage("ajax error, action: <b>"+action+"</b> not found");
return(false);
}
if(response.success == undefined){
t.showErrorMessage("The 'success' param is a must!");
return(false);
}
if(response.success == false){
t.showErrorMessage(response.message);
return(false);
}
//success actions:
//run a success event function
if(typeof successFunction == "function")
successFunction(response);
else{
if(response.message)
showSuccessMessage(response.message);
}
if(response.is_redirect)
location.href=response.redirect_url;
},
error:function(jqXHR, textStatus, errorThrown){
hideAjaxLoader();
if(textStatus == "parsererror")
t.debug(jqXHR.responseText);
t.showErrorMessage("Ajax Error!!! " + textStatus);
}
});
}//ajaxrequest
/**
* open new add image dialog
*/
var openNewImageDialog = function(title,onInsert,isMultiple){
if(isMultiple == undefined)
isMultiple = false;
// Media Library params
var frame = wp.media({
title : title,
multiple : isMultiple,
library : { type : 'image'},
button : { text : 'Insert' }
});
// Runs on select
frame.on('select',function(){
var objSettings = frame.state().get('selection').first().toJSON();
var selection = frame.state().get('selection');
var arrImages = [];
if(isMultiple == true){ //return image object when multiple
selection.map( function( attachment ) {
var objImage = attachment.toJSON();
var obj = {};
obj.url = objImage.url;
obj.id = objImage.id;
arrImages.push(obj);
});
onInsert(arrImages);
}else{ //return image url and id - when single
onInsert(objSettings.url,objSettings.id);
}
});
// Open ML
frame.open();
}
/**
* open old add image dialog
*/
var openOldImageDialog = function(title,onInsert){
var params = "type=image&post_id=0&TB_iframe=true";
params = encodeURI(params);
tb_show(title,'media-upload.php?'+params);
window.send_to_editor = function(html) {
tb_remove();
var urlImage = jQuery(html).attr('src');
if(!urlImage || urlImage == undefined || urlImage == "")
var urlImage = jQuery('img',html).attr('src');
onInsert(urlImage,""); //return empty id, it can be changed
}
}
t.openAddImageDialog = function(title,onInsert,isMultiple){
if(!title)
title = 'Select Image';
if(typeof wp != "undefined" && typeof wp.media != "undefined")
openNewImageDialog(title,onInsert,isMultiple);
else{
openOldImageDialog(title,onInsert);
}
}
/**
* load css file on the fly
* replace current item if exists
*/
t.loadCssFile = function(urlCssFile,replaceID){
var rand = Math.floor((Math.random()*100000)+1);
urlCssFile += "?rand="+rand;
if(replaceID)
jQuery("#"+replaceID).remove();
jQuery("head").append("<link>");
var css = jQuery("head").children(":last");
css.attr({
rel: "stylesheet",
type: "text/css",
href: urlCssFile
});
//replace current element
if(replaceID)
css.attr({id:replaceID});
}
/**
* get show image url
*/
t.getUrlShowImage = function(imageUrl,width,height,exact){
var filepath = imageUrl.replace(g_urlContent,"");
//if not internal image - return normal image url
if(filepath == imageUrl)
return(imageUrl);
var urlImage = g_urlAjaxShowImage+"&img="+filepath;
if(width)
urlImage += "&w="+width;
if(height)
urlImage += "&h="+height;
if(exact && exact == true)
urlImage += "&t=exact";
return(urlImage);
}
/**
* set html to youtube dialog
* if empty data - clear the dialog
*/
var setYoutubeDialogHtml = function(data){
//if empty data - clear the dialog
if(!data){
jQuery("#video_content").html("");
return(false);
}
var thumb = data.thumb_medium;
var html = '<div class="video-content-title">'+data.title+'</div>';
html += '<img src="'+thumb.url+'" width="'+thumb.width+'" height="'+thumb.height+'" alt="thumbnail">';
html += '<div class="video-content-description">'+data.desc_small+'</div>';
jQuery("#video_content").html(html);
}
/**
* pass youtube id or youtube url, and get the id
*/
var getYoutubeIDFromUrl = function(url){
url = jQuery.trim(url);
var video_id = url.split('v=')[1];
if(video_id){
var ampersandPosition = video_id.indexOf('&');
if(ampersandPosition != -1) {
video_id = video_id.substring(0, ampersandPosition);
}
}else{
video_id = url;
}
return(video_id);
}
/**
* get vimeo id from url
*/
var getVimeoIDFromUrl = function(url){
url = jQuery.trim(url);
var video_id = url.replace(/[^0-9]+/g, '');
video_id = jQuery.trim(video_id);
return(video_id);
}
/**
* youtube callback script, set and store youtube data, and add it to dialog
*/
t.onYoutubeCallback = function(obj){
jQuery("#youtube_loader").hide();
var desc_small_size = 200;
//prepare data
var entry = obj.entry;
var data = {};
data.id = jQuery("#youtube_id").val();
data.id = jQuery.trim(data.id);
data.video_type = "youtube";
data.title = entry.title.$t;
data.author = entry.author[0].name.$t;
data.link = entry.link[0].href;
data.description = entry.media$group.media$description.$t;
data.desc_small = data.description;
if(data.description.length > desc_small_size)
data.desc_small = data.description.slice(0,desc_small_size)+"...";
var thumbnails = entry.media$group.media$thumbnail;
data.thumb_small = {url:thumbnails[0].url,width:thumbnails[0].width,height:thumbnails[0].height};
data.thumb_medium = {url:thumbnails[1].url,width:thumbnails[1].width,height:thumbnails[1].height};
data.thumb_big = {url:thumbnails[2].url,width:thumbnails[2].width,height:thumbnails[2].height};
//set html in dialog
setYoutubeDialogHtml(data);
//set the youtube arguments
var objArguments = jQuery("#input_video_arguments");
if(objArguments.val() == "")
objArguments.val(objArguments.data("youtube"));
//store last video data
lastVideoData = data;
//show controls:
jQuery("#video_hidden_controls").show();
}
/**
* vimeo callback script, set and store vimeo data, and add it to dialog
*/
t.onVimeoCallback = function(obj){
jQuery("#vimeo_loader").hide();
var desc_small_size = 200;
obj = obj[0];
var data = {};
data.video_type = "vimeo";
data.id = obj.id;
data.id = jQuery.trim(data.id);
data.title = obj.title;
data.link = obj.url;
data.author = obj.user_name;
data.description = obj.description;
if(data.description.length > desc_small_size)
data.desc_small = data.description.slice(0,desc_small_size)+"...";
data.thumb_large = {url:obj.thumbnail_large,width:640,height:360};
data.thumb_medium = {url:obj.thumbnail_medium,width:200,height:150};
data.thumb_small = {url:obj.thumbnail_small,width:100,height:75};
//set html in dialog
setYoutubeDialogHtml(data);
//set the youtube arguments
var objArguments = jQuery("#input_video_arguments");
objArguments.val(objArguments.data("vimeo"));
//store last video data
lastVideoData = data;
//show controls:
jQuery("#video_hidden_controls").show();
}
/**
* show error message on the dialog
*/
t.videoDialogOnError = function(){
//if ok, don't do nothing
if(jQuery("#video_hidden_controls").is(":visible"))
return(false);
//if error - show message
jQuery("#youtube_loader").hide();
var html = "<div class='video-content-error'>Video Not Found!</div>";
jQuery("#video_content").html(html);
}
/**
* update video size enabled disabled according fullwidth properties
*/
var updateVideoSizeProps = function(){
var isFullwidth = jQuery("#input_video_fullwidth").is(":checked");
if(isFullwidth == true){ //disable
jQuery("#video_size_wrapper").addClass("text-disabled");
jQuery("#input_video_width, #input_video_height").addClass("input-disabled");
}else{ //enable
jQuery("#video_size_wrapper").removeClass("text-disabled");
jQuery("#input_video_width, #input_video_height").removeClass("input-disabled");
}
}
/**
* open dialog for youtube or vimeo import , add / update
*/
t.openVideoDialog = function(callback,objCurrentVideoData){
lastVideoCallback = callback;
var dialogVideo = jQuery("#dialog_video");
//set buttons:
var buttons = {
"Close":function(){
dialogVideo.dialog("close");
}
};
//clear the dialog content
setYoutubeDialogHtml(false);
//clear the fields
jQuery("#input_video_arguments").val("");
jQuery("#input_video_autoplay").prop("checked","");
jQuery("#input_video_nextslide").prop("checked","");
jQuery("#input_video_fullwidth").prop("checked","");
jQuery("#youtube_id").val("");
jQuery("#vimeo_id").val("");
jQuery("#video_hidden_controls").hide();
var buttonVideoAdd = jQuery("#button-video-add");
buttonVideoAdd.text(buttonVideoAdd.data("textadd"));
//open the dialog
dialogVideo.dialog({
buttons:buttons,
minWidth:700,
minHeight:550,
modal:true
});
//if update dialog open:
if(objCurrentVideoData)
setVideoDialogUpdateMode(objCurrentVideoData);
updateVideoSizeProps();
}
/**
* prepare the dialog for video update
*/
var setVideoDialogUpdateMode = function(data){
data.id = jQuery.trim(data.id);
//set mode and video id
switch(data.video_type){
case "youtube":
jQuery("#video_radio_youtube").trigger("click");
jQuery("#youtube_id").val(data.id);
break;
case "vimeo":
jQuery("#video_radio_vimeo").trigger("click");
jQuery("#vimeo_id").val(data.id);
break;
case "html5":
jQuery("#html5_url_poster").val(data.urlPoster);
jQuery("#html5_url_mp4").val(data.urlMp4);
jQuery("#html5_url_webm").val(data.urlWebm);
jQuery("#html5_url_ogv").val(data.urlOgv);
jQuery("#video_radio_html5").trigger("click");
break;
}
//set width and height:
jQuery("#input_video_width").val(data.width);
jQuery("#input_video_height").val(data.height);
jQuery("#input_video_arguments").val(data.args);
if(data.autoplay && data.autoplay == true)
jQuery("#input_video_autoplay").prop("checked","checked");
else
jQuery("#input_video_autoplay").prop("checked","");
if(data.nextslide && data.nextslide == true)
jQuery("#input_video_nextslide").prop("checked","checked");
else
jQuery("#input_video_nextslide").prop("checked","");
if(data.fullwidth && data.fullwidth == true)
jQuery("#input_video_fullwidth").prop("checked","checked");
else
jQuery("#input_video_fullwidth").prop("checked","");
//change button text:
var buttonVideoAdd = jQuery("#button-video-add");
buttonVideoAdd.text(buttonVideoAdd.data("textupdate"));
//search
switch(data.video_type){
case "youtube":
jQuery("#button_youtube_search").trigger("click");
break;
case "vimeo":
jQuery("#button_vimeo_search").trigger("click");
break;
}
}
//add params from textboxes to object
var addTextboxParamsToObj = function(obj){
obj.width = jQuery("#input_video_width").val();
obj.height = jQuery("#input_video_height").val();
obj.args = jQuery("#input_video_arguments").val();
obj.autoplay = jQuery("#input_video_autoplay").is(":checked");
obj.nextslide = jQuery("#input_video_nextslide").is(":checked");
obj.fullwidth = jQuery("#input_video_fullwidth").is(":checked");
return(obj);
}
/**
* init video dialog buttons
*/
var initVideoDialog = function(){
//set youtube radio checked:
jQuery("#video_radio_youtube").prop("checked",true);
//set radio boxes:
jQuery("#video_radio_vimeo").click(function(){
jQuery("#video_block_youtube").hide();
jQuery("#video_block_html5").hide();
jQuery("#video_hidden_controls").hide();
jQuery("#video_content").show();
jQuery("#video_block_vimeo").show();
});
jQuery("#video_radio_youtube").click(function(){
jQuery("#video_block_vimeo").hide();
jQuery("#video_block_html5").hide();
jQuery("#video_hidden_controls").hide();
jQuery("#video_content").show();
jQuery("#video_block_youtube").show();
});
jQuery("#video_radio_html5").click(function(){
jQuery("#video_block_vimeo").hide();
jQuery("#video_block_youtube").hide();
jQuery("#video_block_html5").show();
jQuery("#video_content").hide();
jQuery("#video_hidden_controls").show();
});
//set youtube search action
jQuery("#button_youtube_search").click(function(){
//init data
setYoutubeDialogHtml(false);
jQuery("#video_hidden_controls").hide();
jQuery("#youtube_loader").show();
var youtubeID = jQuery("#youtube_id").val();
youtubeID = jQuery.trim(youtubeID);
youtubeID = getYoutubeIDFromUrl(youtubeID);
var urlAPI = "http://gdata.youtube.com/feeds/api/videos/"+youtubeID+"?v=2&alt=json-in-script&callback=UniteAdminRev.onYoutubeCallback";
jQuery.getScript(urlAPI);
//handle not found:
setTimeout("UniteAdminRev.videoDialogOnError()",2000);
});
//add the selected video to the callback function
jQuery("#button-video-add").click(function(){
var html5Checked = jQuery("#video_radio_html5").prop("checked");
if(html5Checked){ //in case of html5
var obj = {};
obj.video_type = "html5";
obj.urlPoster = jQuery("#html5_url_poster").val();
obj.urlMp4 = jQuery("#html5_url_mp4").val();
obj.urlWebm = jQuery("#html5_url_webm").val();
obj.urlOgv = jQuery("#html5_url_ogv").val();
obj.width = jQuery("#input_video_width").val();
obj.height = jQuery("#input_video_height").val();
obj = addTextboxParamsToObj(obj);
if(typeof lastVideoCallback == "function")
lastVideoCallback(obj);
jQuery("#dialog_video").dialog("close");
}else{ //in case of vimeo and youtube
if(!lastVideoData)
return(false);
lastVideoData = addTextboxParamsToObj(lastVideoData);
if(typeof lastVideoCallback == "function")
lastVideoCallback(lastVideoData);
jQuery("#dialog_video").dialog("close");
}
});
//set vimeo search
jQuery("#button_vimeo_search").click(function(){
//init data
setYoutubeDialogHtml(false);
jQuery("#video_hidden_controls").hide();
jQuery("#vimeo_loader").show();
var vimeoID = jQuery("#vimeo_id").val();
vimeoID = jQuery.trim(vimeoID);
vimeoID = getVimeoIDFromUrl(vimeoID);
var urlAPI = 'http://www.vimeo.com/api/v2/video/' + vimeoID + '.json?callback=UniteAdminRev.onVimeoCallback';
jQuery.getScript(urlAPI);
});
jQuery("#input_video_fullwidth").click(updateVideoSizeProps);
}//end initVideoDialog
/**
* init general settings dialog
*/
var initGeneralSettings = function(){
//button general settings - open dialog
jQuery("#button_general_settings").click(function(){
jQuery("#loader_general_settings").hide();
jQuery("#dialog_general_settings").dialog({
minWidth:800,
minHeight:500,
modal:true
});
});
//button save general settings
jQuery("#button_save_general_settings").click(function(){
var data = UniteSettingsRev.getSettingsObject("form_general_settings");
jQuery("#loader_general_settings").show();
UniteAdminRev.ajaxRequest("update_general_settings",data,function(response){
jQuery("#loader_general_settings").hide();
jQuery("#dialog_general_settings").dialog("close");
});
});
}
//run the init function
jQuery(document).ready(function(){
initVideoDialog();
//init update dialog:
jQuery("#button_upload_plugin").click(function(){
jQuery("#dialog_update_plugin").dialog({
minWidth:600,
minHeight:400,
modal:true
});
});
//update text operation
jQuery("#button_update_text").click(function(){
UniteAdminRev.ajaxRequest("update_text","",function(response){
alert(response.message);
});
});
initGeneralSettings();
});
}
//user functions:
function trace(data,clear){
UniteAdminRev.trace(data,clear);
}
function debug(data){
UniteAdminRev.debug(data);
}

View File

@ -0,0 +1,174 @@
.CodeMirror {
line-height: 1em;
font-family: monospace;
/* Necessary so the scrollbar can be absolutely positioned within the wrapper on Lion. */
position: relative;
/* This prevents unwanted scrollbars from showing up on the body and wrapper in IE. */
overflow: hidden;
}
.CodeMirror-scroll {
overflow: auto;
height: 300px;
/* This is needed to prevent an IE[67] bug where the scrolled content
is visible outside of the scrolling box. */
position: relative;
outline: none;
}
/* Vertical scrollbar */
.CodeMirror-scrollbar {
position: absolute;
right: 0; top: 0;
overflow-x: hidden;
overflow-y: scroll;
z-index: 5;
}
.CodeMirror-scrollbar-inner {
/* This needs to have a nonzero width in order for the scrollbar to appear
in Firefox and IE9. */
width: 1px;
}
.CodeMirror-scrollbar.cm-sb-overlap {
/* Ensure that the scrollbar appears in Lion, and that it overlaps the content
rather than sitting to the right of it. */
position: absolute;
z-index: 1;
float: none;
right: 0;
min-width: 12px;
}
.CodeMirror-scrollbar.cm-sb-nonoverlap {
min-width: 12px;
}
.CodeMirror-scrollbar.cm-sb-ie7 {
min-width: 18px;
}
.CodeMirror-gutter {
position: absolute; left: 0; top: 0;
z-index: 10;
background-color: #f7f7f7;
border-right: 1px solid #eee;
min-width: 2em;
height: 100%;
}
.CodeMirror-gutter-text {
color: #aaa;
text-align: right;
padding: .4em .2em .4em .4em;
white-space: pre !important;
cursor: default;
}
.CodeMirror-lines {
padding: .4em;
white-space: pre;
cursor: text;
}
.CodeMirror pre {
-moz-border-radius: 0;
-webkit-border-radius: 0;
-o-border-radius: 0;
border-radius: 0;
border-width: 0; margin: 0; padding: 0; background: transparent;
font-family: inherit;
font-size: inherit;
padding: 0; margin: 0;
white-space: pre;
word-wrap: normal;
line-height: inherit;
color: inherit;
overflow: visible;
}
.CodeMirror-wrap pre {
word-wrap: break-word;
white-space: pre-wrap;
word-break: normal;
}
.CodeMirror-wrap .CodeMirror-scroll {
overflow-x: hidden;
}
.CodeMirror textarea {
outline: none !important;
}
.CodeMirror pre.CodeMirror-cursor {
z-index: 10;
position: absolute;
visibility: hidden;
border-left: 1px solid black;
border-right: none;
width: 0;
}
.cm-keymap-fat-cursor pre.CodeMirror-cursor {
width: auto;
border: 0;
background: transparent;
background: rgba(0, 200, 0, .4);
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr=#6600c800, endColorstr=#4c00c800);
}
/* Kludge to turn off filter in ie9+, which also accepts rgba */
.cm-keymap-fat-cursor pre.CodeMirror-cursor:not(#nonsense_id) {
filter: progid:DXImageTransform.Microsoft.gradient(enabled=false);
}
.CodeMirror pre.CodeMirror-cursor.CodeMirror-overwrite {}
.CodeMirror-focused pre.CodeMirror-cursor {
visibility: visible;
}
div.CodeMirror-selected { background: #d9d9d9; }
.CodeMirror-focused div.CodeMirror-selected { background: #d7d4f0; }
.CodeMirror-searching {
background: #ffa;
background: rgba(255, 255, 0, .4);
}
/* Default theme */
.cm-s-default span.cm-keyword {color: #708;}
.cm-s-default span.cm-atom {color: #219;}
.cm-s-default span.cm-number {color: #164;}
.cm-s-default span.cm-def {color: #00f;}
.cm-s-default span.cm-variable {color: black;}
.cm-s-default span.cm-variable-2 {color: #05a;}
.cm-s-default span.cm-variable-3 {color: #085;}
.cm-s-default span.cm-property {color: black;}
.cm-s-default span.cm-operator {color: black;}
.cm-s-default span.cm-comment {color: #a50;}
.cm-s-default span.cm-string {color: #a11;}
.cm-s-default span.cm-string-2 {color: #f50;}
.cm-s-default span.cm-meta {color: #555;}
.cm-s-default span.cm-error {color: #f00;}
.cm-s-default span.cm-qualifier {color: #555;}
.cm-s-default span.cm-builtin {color: #30a;}
.cm-s-default span.cm-bracket {color: #997;}
.cm-s-default span.cm-tag {color: #170;}
.cm-s-default span.cm-attribute {color: #00c;}
.cm-s-default span.cm-header {color: blue;}
.cm-s-default span.cm-quote {color: #090;}
.cm-s-default span.cm-hr {color: #999;}
.cm-s-default span.cm-link {color: #00c;}
span.cm-header, span.cm-strong {font-weight: bold;}
span.cm-em {font-style: italic;}
span.cm-emstrong {font-style: italic; font-weight: bold;}
span.cm-link {text-decoration: underline;}
span.cm-invalidchar {color: #f00;}
div.CodeMirror span.CodeMirror-matchingbracket {color: #0f0;}
div.CodeMirror span.CodeMirror-nonmatchingbracket {color: #f22;}
@media print {
/* Hide the cursor when printing */
.CodeMirror pre.CodeMirror-cursor {
visibility: hidden;
}
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,448 @@
CodeMirror.defineMode("css", function(config) {
var indentUnit = config.indentUnit, type;
var atMediaTypes = keySet([
"all", "aural", "braille", "handheld", "print", "projection", "screen",
"tty", "tv", "embossed"
]);
var atMediaFeatures = keySet([
"width", "min-width", "max-width", "height", "min-height", "max-height",
"device-width", "min-device-width", "max-device-width", "device-height",
"min-device-height", "max-device-height", "aspect-ratio",
"min-aspect-ratio", "max-aspect-ratio", "device-aspect-ratio",
"min-device-aspect-ratio", "max-device-aspect-ratio", "color", "min-color",
"max-color", "color-index", "min-color-index", "max-color-index",
"monochrome", "min-monochrome", "max-monochrome", "resolution",
"min-resolution", "max-resolution", "scan", "grid"
]);
var propertyKeywords = keySet([
"align-content", "align-items", "align-self", "alignment-adjust",
"alignment-baseline", "anchor-point", "animation", "animation-delay",
"animation-direction", "animation-duration", "animation-iteration-count",
"animation-name", "animation-play-state", "animation-timing-function",
"appearance", "azimuth", "backface-visibility", "background",
"background-attachment", "background-clip", "background-color",
"background-image", "background-origin", "background-position",
"background-repeat", "background-size", "baseline-shift", "binding",
"bleed", "bookmark-label", "bookmark-level", "bookmark-state",
"bookmark-target", "border", "border-bottom", "border-bottom-color",
"border-bottom-left-radius", "border-bottom-right-radius",
"border-bottom-style", "border-bottom-width", "border-collapse",
"border-color", "border-image", "border-image-outset",
"border-image-repeat", "border-image-slice", "border-image-source",
"border-image-width", "border-left", "border-left-color",
"border-left-style", "border-left-width", "border-radius", "border-right",
"border-right-color", "border-right-style", "border-right-width",
"border-spacing", "border-style", "border-top", "border-top-color",
"border-top-left-radius", "border-top-right-radius", "border-top-style",
"border-top-width", "border-width", "bottom", "box-decoration-break",
"box-shadow", "box-sizing", "break-after", "break-before", "break-inside",
"caption-side", "clear", "clip", "color", "color-profile", "column-count",
"column-fill", "column-gap", "column-rule", "column-rule-color",
"column-rule-style", "column-rule-width", "column-span", "column-width",
"columns", "content", "counter-increment", "counter-reset", "crop", "cue",
"cue-after", "cue-before", "cursor", "direction", "display",
"dominant-baseline", "drop-initial-after-adjust",
"drop-initial-after-align", "drop-initial-before-adjust",
"drop-initial-before-align", "drop-initial-size", "drop-initial-value",
"elevation", "empty-cells", "fit", "fit-position", "flex", "flex-basis",
"flex-direction", "flex-flow", "flex-grow", "flex-shrink", "flex-wrap",
"float", "float-offset", "font", "font-feature-settings", "font-family",
"font-kerning", "font-language-override", "font-size", "font-size-adjust",
"font-stretch", "font-style", "font-synthesis", "font-variant",
"font-variant-alternates", "font-variant-caps", "font-variant-east-asian",
"font-variant-ligatures", "font-variant-numeric", "font-variant-position",
"font-weight", "grid-cell", "grid-column", "grid-column-align",
"grid-column-sizing", "grid-column-span", "grid-columns", "grid-flow",
"grid-row", "grid-row-align", "grid-row-sizing", "grid-row-span",
"grid-rows", "grid-template", "hanging-punctuation", "height", "hyphens",
"icon", "image-orientation", "image-rendering", "image-resolution",
"inline-box-align", "justify-content", "left", "letter-spacing",
"line-break", "line-height", "line-stacking", "line-stacking-ruby",
"line-stacking-shift", "line-stacking-strategy", "list-style",
"list-style-image", "list-style-position", "list-style-type", "margin",
"margin-bottom", "margin-left", "margin-right", "margin-top",
"marker-offset", "marks", "marquee-direction", "marquee-loop",
"marquee-play-count", "marquee-speed", "marquee-style", "max-height",
"max-width", "min-height", "min-width", "move-to", "nav-down", "nav-index",
"nav-left", "nav-right", "nav-up", "opacity", "order", "orphans", "outline",
"outline-color", "outline-offset", "outline-style", "outline-width",
"overflow", "overflow-style", "overflow-wrap", "overflow-x", "overflow-y",
"padding", "padding-bottom", "padding-left", "padding-right", "padding-top",
"page", "page-break-after", "page-break-before", "page-break-inside",
"page-policy", "pause", "pause-after", "pause-before", "perspective",
"perspective-origin", "pitch", "pitch-range", "play-during", "position",
"presentation-level", "punctuation-trim", "quotes", "rendering-intent",
"resize", "rest", "rest-after", "rest-before", "richness", "right",
"rotation", "rotation-point", "ruby-align", "ruby-overhang",
"ruby-position", "ruby-span", "size", "speak", "speak-as", "speak-header",
"speak-numeral", "speak-punctuation", "speech-rate", "stress", "string-set",
"tab-size", "table-layout", "target", "target-name", "target-new",
"target-position", "text-align", "text-align-last", "text-decoration",
"text-decoration-color", "text-decoration-line", "text-decoration-skip",
"text-decoration-style", "text-emphasis", "text-emphasis-color",
"text-emphasis-position", "text-emphasis-style", "text-height",
"text-indent", "text-justify", "text-outline", "text-shadow",
"text-space-collapse", "text-transform", "text-underline-position",
"text-wrap", "top", "transform", "transform-origin", "transform-style",
"transition", "transition-delay", "transition-duration",
"transition-property", "transition-timing-function", "unicode-bidi",
"vertical-align", "visibility", "voice-balance", "voice-duration",
"voice-family", "voice-pitch", "voice-range", "voice-rate", "voice-stress",
"voice-volume", "volume", "white-space", "widows", "width", "word-break",
"word-spacing", "word-wrap", "z-index"
]);
var colorKeywords = keySet([
"black", "silver", "gray", "white", "maroon", "red", "purple", "fuchsia",
"green", "lime", "olive", "yellow", "navy", "blue", "teal", "aqua"
]);
var valueKeywords = keySet([
"above", "absolute", "activeborder", "activecaption", "afar",
"after-white-space", "ahead", "alias", "all", "all-scroll", "alternate",
"always", "amharic", "amharic-abegede", "antialiased", "appworkspace",
"arabic-indic", "armenian", "asterisks", "auto", "avoid", "background",
"backwards", "baseline", "below", "bidi-override", "binary", "bengali",
"blink", "block", "block-axis", "bold", "bolder", "border", "border-box",
"both", "bottom", "break-all", "break-word", "button", "button-bevel",
"buttonface", "buttonhighlight", "buttonshadow", "buttontext", "cambodian",
"capitalize", "caps-lock-indicator", "caption", "captiontext", "caret",
"cell", "center", "checkbox", "circle", "cjk-earthly-branch",
"cjk-heavenly-stem", "cjk-ideographic", "clear", "clip", "close-quote",
"col-resize", "collapse", "compact", "condensed", "contain", "content",
"content-box", "context-menu", "continuous", "copy", "cover", "crop",
"cross", "crosshair", "currentcolor", "cursive", "dashed", "decimal",
"decimal-leading-zero", "default", "default-button", "destination-atop",
"destination-in", "destination-out", "destination-over", "devanagari",
"disc", "discard", "document", "dot-dash", "dot-dot-dash", "dotted",
"double", "down", "e-resize", "ease", "ease-in", "ease-in-out", "ease-out",
"element", "ellipsis", "embed", "end", "ethiopic", "ethiopic-abegede",
"ethiopic-abegede-am-et", "ethiopic-abegede-gez", "ethiopic-abegede-ti-er",
"ethiopic-abegede-ti-et", "ethiopic-halehame-aa-er",
"ethiopic-halehame-aa-et", "ethiopic-halehame-am-et",
"ethiopic-halehame-gez", "ethiopic-halehame-om-et",
"ethiopic-halehame-sid-et", "ethiopic-halehame-so-et",
"ethiopic-halehame-ti-er", "ethiopic-halehame-ti-et",
"ethiopic-halehame-tig", "ew-resize", "expanded", "extra-condensed",
"extra-expanded", "fantasy", "fast", "fill", "fixed", "flat", "footnotes",
"forwards", "from", "geometricPrecision", "georgian", "graytext", "groove",
"gujarati", "gurmukhi", "hand", "hangul", "hangul-consonant", "hebrew",
"help", "hidden", "hide", "higher", "highlight", "highlighttext",
"hiragana", "hiragana-iroha", "horizontal", "hsl", "hsla", "icon", "ignore",
"inactiveborder", "inactivecaption", "inactivecaptiontext", "infinite",
"infobackground", "infotext", "inherit", "initial", "inline", "inline-axis",
"inline-block", "inline-table", "inset", "inside", "intrinsic", "invert",
"italic", "justify", "kannada", "katakana", "katakana-iroha", "khmer",
"landscape", "lao", "large", "larger", "left", "level", "lighter",
"line-through", "linear", "lines", "list-item", "listbox", "listitem",
"local", "logical", "loud", "lower", "lower-alpha", "lower-armenian",
"lower-greek", "lower-hexadecimal", "lower-latin", "lower-norwegian",
"lower-roman", "lowercase", "ltr", "malayalam", "match",
"media-controls-background", "media-current-time-display",
"media-fullscreen-button", "media-mute-button", "media-play-button",
"media-return-to-realtime-button", "media-rewind-button",
"media-seek-back-button", "media-seek-forward-button", "media-slider",
"media-sliderthumb", "media-time-remaining-display", "media-volume-slider",
"media-volume-slider-container", "media-volume-sliderthumb", "medium",
"menu", "menulist", "menulist-button", "menulist-text",
"menulist-textfield", "menutext", "message-box", "middle", "min-intrinsic",
"mix", "mongolian", "monospace", "move", "multiple", "myanmar", "n-resize",
"narrower", "navy", "ne-resize", "nesw-resize", "no-close-quote", "no-drop",
"no-open-quote", "no-repeat", "none", "normal", "not-allowed", "nowrap",
"ns-resize", "nw-resize", "nwse-resize", "oblique", "octal", "open-quote",
"optimizeLegibility", "optimizeSpeed", "oriya", "oromo", "outset",
"outside", "overlay", "overline", "padding", "padding-box", "painted",
"paused", "persian", "plus-darker", "plus-lighter", "pointer", "portrait",
"pre", "pre-line", "pre-wrap", "preserve-3d", "progress", "push-button",
"radio", "read-only", "read-write", "read-write-plaintext-only", "relative",
"repeat", "repeat-x", "repeat-y", "reset", "reverse", "rgb", "rgba",
"ridge", "right", "round", "row-resize", "rtl", "run-in", "running",
"s-resize", "sans-serif", "scroll", "scrollbar", "se-resize", "searchfield",
"searchfield-cancel-button", "searchfield-decoration",
"searchfield-results-button", "searchfield-results-decoration",
"semi-condensed", "semi-expanded", "separate", "serif", "show", "sidama",
"single", "skip-white-space", "slide", "slider-horizontal",
"slider-vertical", "sliderthumb-horizontal", "sliderthumb-vertical", "slow",
"small", "small-caps", "small-caption", "smaller", "solid", "somali",
"source-atop", "source-in", "source-out", "source-over", "space", "square",
"square-button", "start", "static", "status-bar", "stretch", "stroke",
"sub", "subpixel-antialiased", "super", "sw-resize", "table",
"table-caption", "table-cell", "table-column", "table-column-group",
"table-footer-group", "table-header-group", "table-row", "table-row-group",
"telugu", "text", "text-bottom", "text-top", "textarea", "textfield", "thai",
"thick", "thin", "threeddarkshadow", "threedface", "threedhighlight",
"threedlightshadow", "threedshadow", "tibetan", "tigre", "tigrinya-er",
"tigrinya-er-abegede", "tigrinya-et", "tigrinya-et-abegede", "to", "top",
"transparent", "ultra-condensed", "ultra-expanded", "underline", "up",
"upper-alpha", "upper-armenian", "upper-greek", "upper-hexadecimal",
"upper-latin", "upper-norwegian", "upper-roman", "uppercase", "urdu", "url",
"vertical", "vertical-text", "visible", "visibleFill", "visiblePainted",
"visibleStroke", "visual", "w-resize", "wait", "wave", "white", "wider",
"window", "windowframe", "windowtext", "x-large", "x-small", "xor",
"xx-large", "xx-small", "yellow"
]);
function keySet(array) { var keys = {}; for (var i = 0; i < array.length; ++i) keys[array[i]] = true; return keys; }
function ret(style, tp) {type = tp; return style;}
function tokenBase(stream, state) {
var ch = stream.next();
if (ch == "@") {stream.eatWhile(/[\w\\\-]/); return ret("def", stream.current());}
else if (ch == "/" && stream.eat("*")) {
state.tokenize = tokenCComment;
return tokenCComment(stream, state);
}
else if (ch == "<" && stream.eat("!")) {
state.tokenize = tokenSGMLComment;
return tokenSGMLComment(stream, state);
}
else if (ch == "=") ret(null, "compare");
else if ((ch == "~" || ch == "|") && stream.eat("=")) return ret(null, "compare");
else if (ch == "\"" || ch == "'") {
state.tokenize = tokenString(ch);
return state.tokenize(stream, state);
}
else if (ch == "#") {
stream.eatWhile(/[\w\\\-]/);
return ret("atom", "hash");
}
else if (ch == "!") {
stream.match(/^\s*\w*/);
return ret("keyword", "important");
}
else if (/\d/.test(ch)) {
stream.eatWhile(/[\w.%]/);
return ret("number", "unit");
}
else if (ch === "-") {
if (/\d/.test(stream.peek())) {
stream.eatWhile(/[\w.%]/);
return ret("number", "unit");
} else if (stream.match(/^[^-]+-/)) {
return ret("meta", type);
}
}
else if (/[,+>*\/]/.test(ch)) {
return ret(null, "select-op");
}
else if (ch == "." && stream.match(/^-?[_a-z][_a-z0-9-]*/i)) {
return ret("qualifier", type);
}
else if (ch == ":") {
return ret("operator", ch);
}
else if (/[;{}\[\]\(\)]/.test(ch)) {
return ret(null, ch);
}
else {
stream.eatWhile(/[\w\\\-]/);
return ret("property", "variable");
}
}
function tokenCComment(stream, state) {
var maybeEnd = false, ch;
while ((ch = stream.next()) != null) {
if (maybeEnd && ch == "/") {
state.tokenize = tokenBase;
break;
}
maybeEnd = (ch == "*");
}
return ret("comment", "comment");
}
function tokenSGMLComment(stream, state) {
var dashes = 0, ch;
while ((ch = stream.next()) != null) {
if (dashes >= 2 && ch == ">") {
state.tokenize = tokenBase;
break;
}
dashes = (ch == "-") ? dashes + 1 : 0;
}
return ret("comment", "comment");
}
function tokenString(quote) {
return function(stream, state) {
var escaped = false, ch;
while ((ch = stream.next()) != null) {
if (ch == quote && !escaped)
break;
escaped = !escaped && ch == "\\";
}
if (!escaped) state.tokenize = tokenBase;
return ret("string", "string");
};
}
return {
startState: function(base) {
return {tokenize: tokenBase,
baseIndent: base || 0,
stack: []};
},
token: function(stream, state) {
// Use these terms when applicable (see http://www.xanthir.com/blog/b4E50)
//
// rule** or **ruleset:
// A selector + braces combo, or an at-rule.
//
// declaration block:
// A sequence of declarations.
//
// declaration:
// A property + colon + value combo.
//
// property value:
// The entire value of a property.
//
// component value:
// A single piece of a property value. Like the 5px in
// text-shadow: 0 0 5px blue;. Can also refer to things that are
// multiple terms, like the 1-4 terms that make up the background-size
// portion of the background shorthand.
//
// term:
// The basic unit of author-facing CSS, like a single number (5),
// dimension (5px), string ("foo"), or function. Officially defined
// by the CSS 2.1 grammar (look for the 'term' production)
//
//
// simple selector:
// A single atomic selector, like a type selector, an attr selector, a
// class selector, etc.
//
// compound selector:
// One or more simple selectors without a combinator. div.example is
// compound, div > .example is not.
//
// complex selector:
// One or more compound selectors chained with combinators.
//
// combinator:
// The parts of selectors that express relationships. There are four
// currently - the space (descendant combinator), the greater-than
// bracket (child combinator), the plus sign (next sibling combinator),
// and the tilda (following sibling combinator).
//
// sequence of selectors:
// One or more of the named type of selector chained with commas.
if (stream.eatSpace()) return null;
var style = state.tokenize(stream, state);
// Changing style returned based on context
var context = state.stack[state.stack.length-1];
if (style == "property") {
if (context == "propertyValue"){
if (valueKeywords[stream.current()]) {
style = "string-2";
} else if (colorKeywords[stream.current()]) {
style = "keyword";
} else {
style = "variable-2";
}
} else if (context == "rule") {
if (!propertyKeywords[stream.current()]) {
style += " error";
}
} else if (!context || context == "@media{") {
style = "tag";
} else if (context == "@media") {
if (atMediaTypes[stream.current()]) {
style = "attribute"; // Known attribute
} else if (/^(only|not)$/i.test(stream.current())) {
style = "keyword";
} else if (stream.current().toLowerCase() == "and") {
style = "error"; // "and" is only allowed in @mediaType
} else if (atMediaFeatures[stream.current()]) {
style = "error"; // Known property, should be in @mediaType(
} else {
// Unknown, expecting keyword or attribute, assuming attribute
style = "attribute error";
}
} else if (context == "@mediaType") {
if (atMediaTypes[stream.current()]) {
style = "attribute";
} else if (stream.current().toLowerCase() == "and") {
style = "operator";
} else if (/^(only|not)$/i.test(stream.current())) {
style = "error"; // Only allowed in @media
} else if (atMediaFeatures[stream.current()]) {
style = "error"; // Known property, should be in parentheses
} else {
// Unknown attribute or property, but expecting property (preceded
// by "and"). Should be in parentheses
style = "error";
}
} else if (context == "@mediaType(") {
if (propertyKeywords[stream.current()]) {
// do nothing, remains "property"
} else if (atMediaTypes[stream.current()]) {
style = "error"; // Known property, should be in parentheses
} else if (stream.current().toLowerCase() == "and") {
style = "operator";
} else if (/^(only|not)$/i.test(stream.current())) {
style = "error"; // Only allowed in @media
} else {
style += " error";
}
} else {
style = "error";
}
} else if (style == "atom") {
if(!context || context == "@media{") {
style = "builtin";
} else if (context == "propertyValue") {
if (!/^#([0-9a-fA-f]{3}|[0-9a-fA-f]{6})$/.test(stream.current())) {
style += " error";
}
} else {
style = "error";
}
} else if (context == "@media" && type == "{") {
style = "error";
}
// Push/pop context stack
if (type == "{") {
if (context == "@media" || context == "@mediaType") {
state.stack.pop();
state.stack[state.stack.length-1] = "@media{";
}
else state.stack.push("rule");
}
else if (type == "}") {
state.stack.pop();
if (context == "propertyValue") state.stack.pop();
}
else if (type == "@media") state.stack.push("@media");
else if (context == "@media" && /\b(keyword|attribute)\b/.test(style))
state.stack.push("@mediaType");
else if (context == "@mediaType" && stream.current() == ",") state.stack.pop();
else if (context == "@mediaType" && type == "(") state.stack.push("@mediaType(");
else if (context == "@mediaType(" && type == ")") state.stack.pop();
else if (context == "rule" && type == ":") state.stack.push("propertyValue");
else if (context == "propertyValue" && type == ";") state.stack.pop();
return style;
},
indent: function(state, textAfter) {
var n = state.stack.length;
if (/^\}/.test(textAfter))
n -= state.stack[state.stack.length-1] == "propertyValue" ? 2 : 1;
return state.baseIndent + n * indentUnit;
},
electricChars: "}"
};
});
CodeMirror.defineMIME("text/css", "css");

View File

@ -0,0 +1,164 @@
/**
* Tag-closer extension for CodeMirror.
*
* This extension adds a "closeTag" utility function that can be used with key bindings to
* insert a matching end tag after the ">" character of a start tag has been typed. It can
* also complete "</" if a matching start tag is found. It will correctly ignore signal
* characters for empty tags, comments, CDATA, etc.
*
* The function depends on internal parser state to identify tags. It is compatible with the
* following CodeMirror modes and will ignore all others:
* - htmlmixed
* - xml
*
* See demos/closetag.html for a usage example.
*
* @author Nathan Williams <nathan@nlwillia.net>
* Contributed under the same license terms as CodeMirror.
*/
(function() {
/** Option that allows tag closing behavior to be toggled. Default is true. */
CodeMirror.defaults['closeTagEnabled'] = true;
/** Array of tag names to add indentation after the start tag for. Default is the list of block-level html tags. */
CodeMirror.defaults['closeTagIndent'] = ['applet', 'blockquote', 'body', 'button', 'div', 'dl', 'fieldset', 'form', 'frameset', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'head', 'html', 'iframe', 'layer', 'legend', 'object', 'ol', 'p', 'select', 'table', 'ul'];
/** Array of tag names where an end tag is forbidden. */
CodeMirror.defaults['closeTagVoid'] = ['area', 'base', 'br', 'col', 'command', 'embed', 'hr', 'img', 'input', 'keygen', 'link', 'meta', 'param', 'source', 'track', 'wbr'];
function innerState(cm, state) {
return CodeMirror.innerMode(cm.getMode(), state).state;
}
/**
* Call during key processing to close tags. Handles the key event if the tag is closed, otherwise throws CodeMirror.Pass.
* - cm: The editor instance.
* - ch: The character being processed.
* - indent: Optional. An array of tag names to indent when closing. Omit or pass true to use the default indentation tag list defined in the 'closeTagIndent' option.
* Pass false to disable indentation. Pass an array to override the default list of tag names.
* - vd: Optional. An array of tag names that should not be closed. Omit to use the default void (end tag forbidden) tag list defined in the 'closeTagVoid' option. Ignored in xml mode.
*/
CodeMirror.defineExtension("closeTag", function(cm, ch, indent, vd) {
if (!cm.getOption('closeTagEnabled')) {
throw CodeMirror.Pass;
}
/*
* Relevant structure of token:
*
* htmlmixed
* className
* state
* htmlState
* type
* tagName
* context
* tagName
* mode
*
* xml
* className
* state
* tagName
* type
*/
var pos = cm.getCursor();
var tok = cm.getTokenAt(pos);
var state = innerState(cm, tok.state);
if (state) {
if (ch == '>') {
var type = state.type;
if (tok.className == 'tag' && type == 'closeTag') {
throw CodeMirror.Pass; // Don't process the '>' at the end of an end-tag.
}
cm.replaceSelection('>'); // Mode state won't update until we finish the tag.
pos = {line: pos.line, ch: pos.ch + 1};
cm.setCursor(pos);
tok = cm.getTokenAt(cm.getCursor());
state = innerState(cm, tok.state);
if (!state) throw CodeMirror.Pass;
var type = state.type;
if (tok.className == 'tag' && type != 'selfcloseTag') {
var tagName = state.tagName;
if (tagName.length > 0 && shouldClose(cm, vd, tagName)) {
insertEndTag(cm, indent, pos, tagName);
}
return;
}
// Undo the '>' insert and allow cm to handle the key instead.
cm.setSelection({line: pos.line, ch: pos.ch - 1}, pos);
cm.replaceSelection("");
} else if (ch == '/') {
if (tok.className == 'tag' && tok.string == '<') {
var ctx = state.context, tagName = ctx ? ctx.tagName : '';
if (tagName.length > 0) {
completeEndTag(cm, pos, tagName);
return;
}
}
}
}
throw CodeMirror.Pass; // Bubble if not handled
});
function insertEndTag(cm, indent, pos, tagName) {
if (shouldIndent(cm, indent, tagName)) {
cm.replaceSelection('\n\n</' + tagName + '>', 'end');
cm.indentLine(pos.line + 1);
cm.indentLine(pos.line + 2);
cm.setCursor({line: pos.line + 1, ch: cm.getLine(pos.line + 1).length});
} else {
cm.replaceSelection('</' + tagName + '>');
cm.setCursor(pos);
}
}
function shouldIndent(cm, indent, tagName) {
if (typeof indent == 'undefined' || indent == null || indent == true) {
indent = cm.getOption('closeTagIndent');
}
if (!indent) {
indent = [];
}
return indexOf(indent, tagName.toLowerCase()) != -1;
}
function shouldClose(cm, vd, tagName) {
if (cm.getOption('mode') == 'xml') {
return true; // always close xml tags
}
if (typeof vd == 'undefined' || vd == null) {
vd = cm.getOption('closeTagVoid');
}
if (!vd) {
vd = [];
}
return indexOf(vd, tagName.toLowerCase()) == -1;
}
// C&P from codemirror.js...would be nice if this were visible to utilities.
function indexOf(collection, elt) {
if (collection.indexOf) return collection.indexOf(elt);
for (var i = 0, e = collection.length; i < e; ++i)
if (collection[i] == elt) return i;
return -1;
}
function completeEndTag(cm, pos, tagName) {
cm.replaceSelection('/' + tagName + '>');
cm.setCursor({line: pos.line, ch: pos.ch + tagName.length + 2 });
}
})();

View File

@ -0,0 +1,27 @@
.CodeMirror-dialog {
position: relative;
}
.CodeMirror-dialog > div {
position: absolute;
top: 0; left: 0; right: 0;
background: white;
border-bottom: 1px solid #eee;
z-index: 15;
padding: .1em .8em;
overflow: hidden;
color: #333;
}
.CodeMirror-dialog input {
border: none;
outline: none;
background: transparent;
width: 20em;
color: inherit;
font-family: monospace;
}
.CodeMirror-dialog button {
font-size: 70%;
}

View File

@ -0,0 +1,70 @@
// Open simple dialogs on top of an editor. Relies on dialog.css.
(function() {
function dialogDiv(cm, template) {
var wrap = cm.getWrapperElement();
var dialog = wrap.insertBefore(document.createElement("div"), wrap.firstChild);
dialog.className = "CodeMirror-dialog";
dialog.innerHTML = '<div>' + template + '</div>';
return dialog;
}
CodeMirror.defineExtension("openDialog", function(template, callback) {
var dialog = dialogDiv(this, template);
var closed = false, me = this;
function close() {
if (closed) return;
closed = true;
dialog.parentNode.removeChild(dialog);
}
var inp = dialog.getElementsByTagName("input")[0], button;
if (inp) {
CodeMirror.connect(inp, "keydown", function(e) {
if (e.keyCode == 13 || e.keyCode == 27) {
CodeMirror.e_stop(e);
close();
me.focus();
if (e.keyCode == 13) callback(inp.value);
}
});
inp.focus();
CodeMirror.connect(inp, "blur", close);
} else if (button = dialog.getElementsByTagName("button")[0]) {
CodeMirror.connect(button, "click", function() {
close();
me.focus();
});
button.focus();
CodeMirror.connect(button, "blur", close);
}
return close;
});
CodeMirror.defineExtension("openConfirm", function(template, callbacks) {
var dialog = dialogDiv(this, template);
var buttons = dialog.getElementsByTagName("button");
var closed = false, me = this, blurring = 1;
function close() {
if (closed) return;
closed = true;
dialog.parentNode.removeChild(dialog);
me.focus();
}
buttons[0].focus();
for (var i = 0; i < buttons.length; ++i) {
var b = buttons[i];
(function(callback) {
CodeMirror.connect(b, "click", function(e) {
CodeMirror.e_preventDefault(e);
close();
if (callback) callback(me);
});
})(callbacks[i]);
CodeMirror.connect(b, "blur", function() {
--blurring;
setTimeout(function() { if (blurring <= 0) close(); }, 200);
});
CodeMirror.connect(b, "focus", function() { ++blurring; });
}
});
})();

View File

@ -0,0 +1,196 @@
// the tagRangeFinder function is
// Copyright (C) 2011 by Daniel Glazman <daniel@glazman.org>
// released under the MIT license (../../LICENSE) like the rest of CodeMirror
CodeMirror.tagRangeFinder = function(cm, line, hideEnd) {
var nameStartChar = "A-Z_a-z\\u00C0-\\u00D6\\u00D8-\\u00F6\\u00F8-\\u02FF\\u0370-\\u037D\\u037F-\\u1FFF\\u200C-\\u200D\\u2070-\\u218F\\u2C00-\\u2FEF\\u3001-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFFD";
var nameChar = nameStartChar + "\-\:\.0-9\\u00B7\\u0300-\\u036F\\u203F-\\u2040";
var xmlNAMERegExp = new RegExp("^[" + nameStartChar + "][" + nameChar + "]*");
var lineText = cm.getLine(line);
var found = false;
var tag = null;
var pos = 0;
while (!found) {
pos = lineText.indexOf("<", pos);
if (-1 == pos) // no tag on line
return;
if (pos + 1 < lineText.length && lineText[pos + 1] == "/") { // closing tag
pos++;
continue;
}
// ok we weem to have a start tag
if (!lineText.substr(pos + 1).match(xmlNAMERegExp)) { // not a tag name...
pos++;
continue;
}
var gtPos = lineText.indexOf(">", pos + 1);
if (-1 == gtPos) { // end of start tag not in line
var l = line + 1;
var foundGt = false;
var lastLine = cm.lineCount();
while (l < lastLine && !foundGt) {
var lt = cm.getLine(l);
var gt = lt.indexOf(">");
if (-1 != gt) { // found a >
foundGt = true;
var slash = lt.lastIndexOf("/", gt);
if (-1 != slash && slash < gt) {
var str = lineText.substr(slash, gt - slash + 1);
if (!str.match( /\/\s*\>/ )) { // yep, that's the end of empty tag
if (hideEnd === true) l++;
return l;
}
}
}
l++;
}
found = true;
}
else {
var slashPos = lineText.lastIndexOf("/", gtPos);
if (-1 == slashPos) { // cannot be empty tag
found = true;
// don't continue
}
else { // empty tag?
// check if really empty tag
var str = lineText.substr(slashPos, gtPos - slashPos + 1);
if (!str.match( /\/\s*\>/ )) { // finally not empty
found = true;
// don't continue
}
}
}
if (found) {
var subLine = lineText.substr(pos + 1);
tag = subLine.match(xmlNAMERegExp);
if (tag) {
// we have an element name, wooohooo !
tag = tag[0];
// do we have the close tag on same line ???
if (-1 != lineText.indexOf("</" + tag + ">", pos)) // yep
{
found = false;
}
// we don't, so we have a candidate...
}
else
found = false;
}
if (!found)
pos++;
}
if (found) {
var startTag = "(\\<\\/" + tag + "\\>)|(\\<" + tag + "\\>)|(\\<" + tag + "\\s)|(\\<" + tag + "$)";
var startTagRegExp = new RegExp(startTag, "g");
var endTag = "</" + tag + ">";
var depth = 1;
var l = line + 1;
var lastLine = cm.lineCount();
while (l < lastLine) {
lineText = cm.getLine(l);
var match = lineText.match(startTagRegExp);
if (match) {
for (var i = 0; i < match.length; i++) {
if (match[i] == endTag)
depth--;
else
depth++;
if (!depth) {
if (hideEnd === true) l++;
return l;
}
}
}
l++;
}
return;
}
};
CodeMirror.braceRangeFinder = function(cm, line, hideEnd) {
var lineText = cm.getLine(line), at = lineText.length, startChar, tokenType;
for (;;) {
var found = lineText.lastIndexOf("{", at);
if (found < 0) break;
tokenType = cm.getTokenAt({line: line, ch: found}).className;
if (!/^(comment|string)/.test(tokenType)) { startChar = found; break; }
at = found - 1;
}
if (startChar == null || lineText.lastIndexOf("}") > startChar) return;
var count = 1, lastLine = cm.lineCount(), end;
outer: for (var i = line + 1; i < lastLine; ++i) {
var text = cm.getLine(i), pos = 0;
for (;;) {
var nextOpen = text.indexOf("{", pos), nextClose = text.indexOf("}", pos);
if (nextOpen < 0) nextOpen = text.length;
if (nextClose < 0) nextClose = text.length;
pos = Math.min(nextOpen, nextClose);
if (pos == text.length) break;
if (cm.getTokenAt({line: i, ch: pos + 1}).className == tokenType) {
if (pos == nextOpen) ++count;
else if (!--count) { end = i; break outer; }
}
++pos;
}
}
if (end == null || end == line + 1) return;
if (hideEnd === true) end++;
return end;
};
CodeMirror.indentRangeFinder = function(cm, line) {
var tabSize = cm.getOption("tabSize");
var myIndent = cm.getLineHandle(line).indentation(tabSize), last;
for (var i = line + 1, end = cm.lineCount(); i < end; ++i) {
var handle = cm.getLineHandle(i);
if (!/^\s*$/.test(handle.text)) {
if (handle.indentation(tabSize) <= myIndent) break;
last = i;
}
}
if (!last) return null;
return last + 1;
};
CodeMirror.newFoldFunction = function(rangeFinder, markText, hideEnd) {
var folded = [];
if (markText == null) markText = '<div style="position: absolute; left: 2px; color:#600">&#x25bc;</div>%N%';
function isFolded(cm, n) {
for (var i = 0; i < folded.length; ++i) {
var start = cm.lineInfo(folded[i].start);
if (!start) folded.splice(i--, 1);
else if (start.line == n) return {pos: i, region: folded[i]};
}
}
function expand(cm, region) {
cm.clearMarker(region.start);
for (var i = 0; i < region.hidden.length; ++i)
cm.showLine(region.hidden[i]);
}
return function(cm, line) {
cm.operation(function() {
var known = isFolded(cm, line);
if (known) {
folded.splice(known.pos, 1);
expand(cm, known.region);
} else {
var end = rangeFinder(cm, line, hideEnd);
if (end == null) return;
var hidden = [];
for (var i = line + 1; i < end; ++i) {
var handle = cm.hideLine(i);
if (handle) hidden.push(handle);
}
var first = cm.setMarker(line, markText);
var region = {start: first, hidden: hidden};
cm.onDeleteLine(first, function() { expand(cm, region); });
folded.push(region);
}
});
};
};

View File

@ -0,0 +1,193 @@
// ============== Formatting extensions ============================
(function() {
// Define extensions for a few modes
CodeMirror.extendMode("css", {
commentStart: "/*",
commentEnd: "*/",
wordWrapChars: [";", "\\{", "\\}"],
autoFormatLineBreaks: function (text) {
return text.replace(new RegExp("(;|\\{|\\})([^\r\n])", "g"), "$1\n$2");
}
});
function jsNonBreakableBlocks(text) {
var nonBreakableRegexes = [/for\s*?\((.*?)\)/,
/\"(.*?)(\"|$)/,
/\'(.*?)(\'|$)/,
/\/\*(.*?)(\*\/|$)/,
/\/\/.*/];
var nonBreakableBlocks = [];
for (var i = 0; i < nonBreakableRegexes.length; i++) {
var curPos = 0;
while (curPos < text.length) {
var m = text.substr(curPos).match(nonBreakableRegexes[i]);
if (m != null) {
nonBreakableBlocks.push({
start: curPos + m.index,
end: curPos + m.index + m[0].length
});
curPos += m.index + Math.max(1, m[0].length);
}
else { // No more matches
break;
}
}
}
nonBreakableBlocks.sort(function (a, b) {
return a.start - b.start;
});
return nonBreakableBlocks;
}
CodeMirror.extendMode("javascript", {
commentStart: "/*",
commentEnd: "*/",
wordWrapChars: [";", "\\{", "\\}"],
autoFormatLineBreaks: function (text) {
var curPos = 0;
var reLinesSplitter = /(;|\{|\})([^\r\n;])/g;
var nonBreakableBlocks = jsNonBreakableBlocks(text);
if (nonBreakableBlocks != null) {
var res = "";
for (var i = 0; i < nonBreakableBlocks.length; i++) {
if (nonBreakableBlocks[i].start > curPos) { // Break lines till the block
res += text.substring(curPos, nonBreakableBlocks[i].start).replace(reLinesSplitter, "$1\n$2");
curPos = nonBreakableBlocks[i].start;
}
if (nonBreakableBlocks[i].start <= curPos
&& nonBreakableBlocks[i].end >= curPos) { // Skip non-breakable block
res += text.substring(curPos, nonBreakableBlocks[i].end);
curPos = nonBreakableBlocks[i].end;
}
}
if (curPos < text.length)
res += text.substr(curPos).replace(reLinesSplitter, "$1\n$2");
return res;
} else {
return text.replace(reLinesSplitter, "$1\n$2");
}
}
});
CodeMirror.extendMode("xml", {
commentStart: "<!--",
commentEnd: "-->",
wordWrapChars: [">"],
autoFormatLineBreaks: function (text) {
var lines = text.split("\n");
var reProcessedPortion = new RegExp("(^\\s*?<|^[^<]*?)(.+)(>\\s*?$|[^>]*?$)");
var reOpenBrackets = new RegExp("<", "g");
var reCloseBrackets = new RegExp("(>)([^\r\n])", "g");
for (var i = 0; i < lines.length; i++) {
var mToProcess = lines[i].match(reProcessedPortion);
if (mToProcess != null && mToProcess.length > 3) { // The line starts with whitespaces and ends with whitespaces
lines[i] = mToProcess[1]
+ mToProcess[2].replace(reOpenBrackets, "\n$&").replace(reCloseBrackets, "$1\n$2")
+ mToProcess[3];
continue;
}
}
return lines.join("\n");
}
});
function localModeAt(cm, pos) {
return CodeMirror.innerMode(cm.getMode(), cm.getTokenAt(pos).state).mode;
}
function enumerateModesBetween(cm, line, start, end) {
var outer = cm.getMode(), text = cm.getLine(line);
if (end == null) end = text.length;
if (!outer.innerMode) return [{from: start, to: end, mode: outer}];
var state = cm.getTokenAt({line: line, ch: start}).state;
var mode = CodeMirror.innerMode(outer, state).mode;
var found = [], stream = new CodeMirror.StringStream(text);
stream.pos = stream.start = start;
for (;;) {
outer.token(stream, state);
var curMode = CodeMirror.innerMode(outer, state).mode;
if (curMode != mode) {
var cut = stream.start;
// Crappy heuristic to deal with the fact that a change in
// mode can occur both at the end and the start of a token,
// and we don't know which it was.
if (mode.name == "xml" && text.charAt(stream.pos - 1) == ">") cut = stream.pos;
found.push({from: start, to: cut, mode: mode});
start = cut;
mode = curMode;
}
if (stream.pos >= end) break;
stream.start = stream.pos;
}
if (start < end) found.push({from: start, to: end, mode: mode});
return found;
}
// Comment/uncomment the specified range
CodeMirror.defineExtension("commentRange", function (isComment, from, to) {
var curMode = localModeAt(this, from), cm = this;
this.operation(function() {
if (isComment) { // Comment range
cm.replaceRange(curMode.commentEnd, to);
cm.replaceRange(curMode.commentStart, from);
if (from.line == to.line && from.ch == to.ch) // An empty comment inserted - put cursor inside
cm.setCursor(from.line, from.ch + curMode.commentStart.length);
} else { // Uncomment range
var selText = cm.getRange(from, to);
var startIndex = selText.indexOf(curMode.commentStart);
var endIndex = selText.lastIndexOf(curMode.commentEnd);
if (startIndex > -1 && endIndex > -1 && endIndex > startIndex) {
// Take string till comment start
selText = selText.substr(0, startIndex)
// From comment start till comment end
+ selText.substring(startIndex + curMode.commentStart.length, endIndex)
// From comment end till string end
+ selText.substr(endIndex + curMode.commentEnd.length);
}
cm.replaceRange(selText, from, to);
}
});
});
// Applies automatic mode-aware indentation to the specified range
CodeMirror.defineExtension("autoIndentRange", function (from, to) {
var cmInstance = this;
this.operation(function () {
for (var i = from.line; i <= to.line; i++) {
cmInstance.indentLine(i, "smart");
}
});
});
// Applies automatic formatting to the specified range
CodeMirror.defineExtension("autoFormatRange", function (from, to) {
var cm = this;
cm.operation(function () {
for (var cur = from.line, end = to.line; cur <= end; ++cur) {
var f = {line: cur, ch: cur == from.line ? from.ch : 0};
var t = {line: cur, ch: cur == end ? to.ch : null};
var modes = enumerateModesBetween(cm, cur, f.ch, t.ch), mangled = "";
var text = cm.getRange(f, t);
for (var i = 0; i < modes.length; ++i) {
var part = modes.length > 1 ? text.slice(modes[i].from, modes[i].to) : text;
if (mangled) mangled += "\n";
if (modes[i].mode.autoFormatLineBreaks) {
mangled += modes[i].mode.autoFormatLineBreaks(part);
} else mangled += text;
}
if (mangled != text) {
for (var count = 0, pos = mangled.indexOf("\n"); pos != -1; pos = mangled.indexOf("\n", pos + 1), ++count) {}
cm.replaceRange(mangled, f, t);
cur += count;
end += count;
}
}
for (var cur = from.line + 1; cur <= end; ++cur)
cm.indentLine(cur, "smart");
cm.setSelection(from, cm.getCursor(false));
});
});
})();

View File

@ -0,0 +1,134 @@
(function () {
function forEach(arr, f) {
for (var i = 0, e = arr.length; i < e; ++i) f(arr[i]);
}
function arrayContains(arr, item) {
if (!Array.prototype.indexOf) {
var i = arr.length;
while (i--) {
if (arr[i] === item) {
return true;
}
}
return false;
}
return arr.indexOf(item) != -1;
}
function scriptHint(editor, keywords, getToken) {
// Find the token at the cursor
var cur = editor.getCursor(), token = getToken(editor, cur), tprop = token;
// If it's not a 'word-style' token, ignore the token.
if (!/^[\w$_]*$/.test(token.string)) {
token = tprop = {start: cur.ch, end: cur.ch, string: "", state: token.state,
className: token.string == "." ? "property" : null};
}
// If it is a property, find out what it is a property of.
while (tprop.className == "property") {
tprop = getToken(editor, {line: cur.line, ch: tprop.start});
if (tprop.string != ".") return;
tprop = getToken(editor, {line: cur.line, ch: tprop.start});
if (tprop.string == ')') {
var level = 1;
do {
tprop = getToken(editor, {line: cur.line, ch: tprop.start});
switch (tprop.string) {
case ')': level++; break;
case '(': level--; break;
default: break;
}
} while (level > 0);
tprop = getToken(editor, {line: cur.line, ch: tprop.start});
if (tprop.className == 'variable')
tprop.className = 'function';
else return; // no clue
}
if (!context) var context = [];
context.push(tprop);
}
return {list: getCompletions(token, context, keywords),
from: {line: cur.line, ch: token.start},
to: {line: cur.line, ch: token.end}};
}
CodeMirror.javascriptHint = function(editor) {
return scriptHint(editor, javascriptKeywords,
function (e, cur) {return e.getTokenAt(cur);});
};
function getCoffeeScriptToken(editor, cur) {
// This getToken, it is for coffeescript, imitates the behavior of
// getTokenAt method in javascript.js, that is, returning "property"
// type and treat "." as indepenent token.
var token = editor.getTokenAt(cur);
if (cur.ch == token.start + 1 && token.string.charAt(0) == '.') {
token.end = token.start;
token.string = '.';
token.className = "property";
}
else if (/^\.[\w$_]*$/.test(token.string)) {
token.className = "property";
token.start++;
token.string = token.string.replace(/\./, '');
}
return token;
}
CodeMirror.coffeescriptHint = function(editor) {
return scriptHint(editor, coffeescriptKeywords, getCoffeeScriptToken);
};
var stringProps = ("charAt charCodeAt indexOf lastIndexOf substring substr slice trim trimLeft trimRight " +
"toUpperCase toLowerCase split concat match replace search").split(" ");
var arrayProps = ("length concat join splice push pop shift unshift slice reverse sort indexOf " +
"lastIndexOf every some filter forEach map reduce reduceRight ").split(" ");
var funcProps = "prototype apply call bind".split(" ");
var javascriptKeywords = ("break case catch continue debugger default delete do else false finally for function " +
"if in instanceof new null return switch throw true try typeof var void while with").split(" ");
var coffeescriptKeywords = ("and break catch class continue delete do else extends false finally for " +
"if in instanceof isnt new no not null of off on or return switch then throw true try typeof until void while with yes").split(" ");
function getCompletions(token, context, keywords) {
var found = [], start = token.string;
function maybeAdd(str) {
if (str.indexOf(start) == 0 && !arrayContains(found, str)) found.push(str);
}
function gatherCompletions(obj) {
if (typeof obj == "string") forEach(stringProps, maybeAdd);
else if (obj instanceof Array) forEach(arrayProps, maybeAdd);
else if (obj instanceof Function) forEach(funcProps, maybeAdd);
for (var name in obj) maybeAdd(name);
}
if (context) {
// If this is a property, see if it belongs to some object we can
// find in the current environment.
var obj = context.pop(), base;
if (obj.className == "variable")
base = window[obj.string];
else if (obj.className == "string")
base = "";
else if (obj.className == "atom")
base = 1;
else if (obj.className == "function") {
if (window.jQuery != null && (obj.string == '$' || obj.string == 'jQuery') &&
(typeof window.jQuery == 'function'))
base = window.jQuery();
else if (window._ != null && (obj.string == '_') && (typeof window._ == 'function'))
base = window._();
}
while (base != null && context.length)
base = base[context.pop().string];
if (base != null) gatherCompletions(base);
}
else {
// If not, just look in the window object and any local scope
// (reading into JS mode internals to get at the local variables)
for (var v = token.state.localVars; v; v = v.next) maybeAdd(v.name);
gatherCompletions(window);
forEach(keywords, maybeAdd);
}
return found;
}
})();

View File

@ -0,0 +1,51 @@
(function() {
if (!CodeMirror.modeURL) CodeMirror.modeURL = "../mode/%N/%N.js";
var loading = {};
function splitCallback(cont, n) {
var countDown = n;
return function() { if (--countDown == 0) cont(); };
}
function ensureDeps(mode, cont) {
var deps = CodeMirror.modes[mode].dependencies;
if (!deps) return cont();
var missing = [];
for (var i = 0; i < deps.length; ++i) {
if (!CodeMirror.modes.hasOwnProperty(deps[i]))
missing.push(deps[i]);
}
if (!missing.length) return cont();
var split = splitCallback(cont, missing.length);
for (var i = 0; i < missing.length; ++i)
CodeMirror.requireMode(missing[i], split);
}
CodeMirror.requireMode = function(mode, cont) {
if (typeof mode != "string") mode = mode.name;
if (CodeMirror.modes.hasOwnProperty(mode)) return ensureDeps(mode, cont);
if (loading.hasOwnProperty(mode)) return loading[mode].push(cont);
var script = document.createElement("script");
script.src = CodeMirror.modeURL.replace(/%N/g, mode);
var others = document.getElementsByTagName("script")[0];
others.parentNode.insertBefore(script, others);
var list = loading[mode] = [cont];
var count = 0, poll = setInterval(function() {
if (++count > 100) return clearInterval(poll);
if (CodeMirror.modes.hasOwnProperty(mode)) {
clearInterval(poll);
loading[mode] = null;
ensureDeps(mode, function() {
for (var i = 0; i < list.length; ++i) list[i]();
});
}
}, 200);
};
CodeMirror.autoLoadMode = function(instance, mode) {
if (!CodeMirror.modes.hasOwnProperty(mode))
CodeMirror.requireMode(mode, function() {
instance.setOption("mode", instance.getOption("mode"));
});
};
}());

View File

@ -0,0 +1,44 @@
// Define match-highlighter commands. Depends on searchcursor.js
// Use by attaching the following function call to the onCursorActivity event:
//myCodeMirror.matchHighlight(minChars);
// And including a special span.CodeMirror-matchhighlight css class (also optionally a separate one for .CodeMirror-focused -- see demo matchhighlighter.html)
(function() {
var DEFAULT_MIN_CHARS = 2;
function MatchHighlightState() {
this.marked = [];
}
function getMatchHighlightState(cm) {
return cm._matchHighlightState || (cm._matchHighlightState = new MatchHighlightState());
}
function clearMarks(cm) {
var state = getMatchHighlightState(cm);
for (var i = 0; i < state.marked.length; ++i)
state.marked[i].clear();
state.marked = [];
}
function markDocument(cm, className, minChars) {
clearMarks(cm);
minChars = (typeof minChars !== 'undefined' ? minChars : DEFAULT_MIN_CHARS);
if (cm.somethingSelected() && cm.getSelection().replace(/^\s+|\s+$/g, "").length >= minChars) {
var state = getMatchHighlightState(cm);
var query = cm.getSelection();
cm.operation(function() {
if (cm.lineCount() < 2000) { // This is too expensive on big documents.
for (var cursor = cm.getSearchCursor(query); cursor.findNext();) {
//Only apply matchhighlight to the matches other than the one actually selected
if (!(cursor.from().line === cm.getCursor(true).line && cursor.from().ch === cm.getCursor(true).ch))
state.marked.push(cm.markText(cursor.from(), cursor.to(), className));
}
}
});
}
}
CodeMirror.defineExtension("matchHighlight", function(className, minChars) {
markDocument(this, className, minChars);
});
})();

View File

@ -0,0 +1,77 @@
CodeMirror.multiplexingMode = function(outer /*, others */) {
// Others should be {open, close, mode [, delimStyle]} objects
var others = Array.prototype.slice.call(arguments, 1);
var n_others = others.length;
function indexOf(string, pattern, from) {
if (typeof pattern == "string") return string.indexOf(pattern, from);
var m = pattern.exec(from ? string.slice(from) : string);
return m ? m.index + from : -1;
}
return {
startState: function() {
return {
outer: CodeMirror.startState(outer),
innerActive: null,
inner: null
};
},
copyState: function(state) {
return {
outer: CodeMirror.copyState(outer, state.outer),
innerActive: state.innerActive,
inner: state.innerActive && CodeMirror.copyState(state.innerActive.mode, state.inner)
};
},
token: function(stream, state) {
if (!state.innerActive) {
var cutOff = Infinity, oldContent = stream.string;
for (var i = 0; i < n_others; ++i) {
var other = others[i];
var found = indexOf(oldContent, other.open, stream.pos);
if (found == stream.pos) {
stream.match(other.open);
state.innerActive = other;
state.inner = CodeMirror.startState(other.mode, outer.indent ? outer.indent(state.outer, "") : 0);
return other.delimStyle;
} else if (found != -1 && found < cutOff) {
cutOff = found;
}
}
if (cutOff != Infinity) stream.string = oldContent.slice(0, cutOff);
var outerToken = outer.token(stream, state.outer);
if (cutOff != Infinity) stream.string = oldContent;
return outerToken;
} else {
var curInner = state.innerActive, oldContent = stream.string;
var found = indexOf(oldContent, curInner.close, stream.pos);
if (found == stream.pos) {
stream.match(curInner.close);
state.innerActive = state.inner = null;
return curInner.delimStyle;
}
if (found > -1) stream.string = oldContent.slice(0, found);
var innerToken = curInner.mode.token(stream, state.inner);
if (found > -1) stream.string = oldContent;
var cur = stream.current(), found = cur.indexOf(curInner.close);
if (found > -1) stream.backUp(cur.length - found);
return innerToken;
}
},
indent: function(state, textAfter) {
var mode = state.innerActive ? state.innerActive.mode : outer;
if (!mode.indent) return CodeMirror.Pass;
return mode.indent(state.innerActive ? state.inner : state.outer, textAfter);
},
electricChars: outer.electricChars,
innerMode: function(state) {
return state.inner ? {state: state.inner, mode: state.innerActive.mode} : {state: state.outer, mode: outer};
}
};
};

View File

@ -0,0 +1,59 @@
// Utility function that allows modes to be combined. The mode given
// as the base argument takes care of most of the normal mode
// functionality, but a second (typically simple) mode is used, which
// can override the style of text. Both modes get to parse all of the
// text, but when both assign a non-null style to a piece of code, the
// overlay wins, unless the combine argument was true, in which case
// the styles are combined.
// overlayParser is the old, deprecated name
CodeMirror.overlayMode = CodeMirror.overlayParser = function(base, overlay, combine) {
return {
startState: function() {
return {
base: CodeMirror.startState(base),
overlay: CodeMirror.startState(overlay),
basePos: 0, baseCur: null,
overlayPos: 0, overlayCur: null
};
},
copyState: function(state) {
return {
base: CodeMirror.copyState(base, state.base),
overlay: CodeMirror.copyState(overlay, state.overlay),
basePos: state.basePos, baseCur: null,
overlayPos: state.overlayPos, overlayCur: null
};
},
token: function(stream, state) {
if (stream.start == state.basePos) {
state.baseCur = base.token(stream, state.base);
state.basePos = stream.pos;
}
if (stream.start == state.overlayPos) {
stream.pos = stream.start;
state.overlayCur = overlay.token(stream, state.overlay);
state.overlayPos = stream.pos;
}
stream.pos = Math.min(state.basePos, state.overlayPos);
if (stream.eol()) state.basePos = state.overlayPos = 0;
if (state.overlayCur == null) return state.baseCur;
if (state.baseCur != null && combine) return state.baseCur + " " + state.overlayCur;
else return state.overlayCur;
},
indent: base.indent && function(state, textAfter) {
return base.indent(state.base, textAfter);
},
electricChars: base.electricChars,
innerMode: function(state) { return {state: state.base, mode: base}; },
blankLine: function(state) {
if (base.blankLine) base.blankLine(state.base);
if (overlay.blankLine) overlay.blankLine(state.overlay);
}
};
};

View File

@ -0,0 +1,123 @@
(function () {
function forEach(arr, f) {
for (var i = 0, e = arr.length; i < e; ++i) f(arr[i]);
}
function arrayContains(arr, item) {
if (!Array.prototype.indexOf) {
var i = arr.length;
while (i--) {
if (arr[i] === item) {
return true;
}
}
return false;
}
return arr.indexOf(item) != -1;
}
function scriptHint(editor, keywords, getToken) {
// Find the token at the cursor
var cur = editor.getCursor(), token = getToken(editor, cur), tprop = token;
// If it's not a 'word-style' token, ignore the token.
if (!/^[\w$_]*$/.test(token.string)) {
token = tprop = {start: cur.ch, end: cur.ch, string: "", state: token.state,
className: token.string == ":" ? "pig-type" : null};
}
if (!context) var context = [];
context.push(tprop);
var completionList = getCompletions(token, context);
completionList = completionList.sort();
//prevent autocomplete for last word, instead show dropdown with one word
if(completionList.length == 1) {
completionList.push(" ");
}
return {list: completionList,
from: {line: cur.line, ch: token.start},
to: {line: cur.line, ch: token.end}};
}
CodeMirror.pigHint = function(editor) {
return scriptHint(editor, pigKeywordsU, function (e, cur) {return e.getTokenAt(cur);});
};
function toTitleCase(str) {
return str.replace(/(?:^|\s)\w/g, function(match) {
return match.toUpperCase();
});
}
var pigKeywords = "VOID IMPORT RETURNS DEFINE LOAD FILTER FOREACH ORDER CUBE DISTINCT COGROUP "
+ "JOIN CROSS UNION SPLIT INTO IF OTHERWISE ALL AS BY USING INNER OUTER ONSCHEMA PARALLEL "
+ "PARTITION GROUP AND OR NOT GENERATE FLATTEN ASC DESC IS STREAM THROUGH STORE MAPREDUCE "
+ "SHIP CACHE INPUT OUTPUT STDERROR STDIN STDOUT LIMIT SAMPLE LEFT RIGHT FULL EQ GT LT GTE LTE "
+ "NEQ MATCHES TRUE FALSE";
var pigKeywordsU = pigKeywords.split(" ");
var pigKeywordsL = pigKeywords.toLowerCase().split(" ");
var pigTypes = "BOOLEAN INT LONG FLOAT DOUBLE CHARARRAY BYTEARRAY BAG TUPLE MAP";
var pigTypesU = pigTypes.split(" ");
var pigTypesL = pigTypes.toLowerCase().split(" ");
var pigBuiltins = "ABS ACOS ARITY ASIN ATAN AVG BAGSIZE BINSTORAGE BLOOM BUILDBLOOM CBRT CEIL "
+ "CONCAT COR COS COSH COUNT COUNT_STAR COV CONSTANTSIZE CUBEDIMENSIONS DIFF DISTINCT DOUBLEABS "
+ "DOUBLEAVG DOUBLEBASE DOUBLEMAX DOUBLEMIN DOUBLEROUND DOUBLESUM EXP FLOOR FLOATABS FLOATAVG "
+ "FLOATMAX FLOATMIN FLOATROUND FLOATSUM GENERICINVOKER INDEXOF INTABS INTAVG INTMAX INTMIN "
+ "INTSUM INVOKEFORDOUBLE INVOKEFORFLOAT INVOKEFORINT INVOKEFORLONG INVOKEFORSTRING INVOKER "
+ "ISEMPTY JSONLOADER JSONMETADATA JSONSTORAGE LAST_INDEX_OF LCFIRST LOG LOG10 LOWER LONGABS "
+ "LONGAVG LONGMAX LONGMIN LONGSUM MAX MIN MAPSIZE MONITOREDUDF NONDETERMINISTIC OUTPUTSCHEMA "
+ "PIGSTORAGE PIGSTREAMING RANDOM REGEX_EXTRACT REGEX_EXTRACT_ALL REPLACE ROUND SIN SINH SIZE "
+ "SQRT STRSPLIT SUBSTRING SUM STRINGCONCAT STRINGMAX STRINGMIN STRINGSIZE TAN TANH TOBAG "
+ "TOKENIZE TOMAP TOP TOTUPLE TRIM TEXTLOADER TUPLESIZE UCFIRST UPPER UTF8STORAGECONVERTER";
var pigBuiltinsU = pigBuiltins.split(" ").join("() ").split(" ");
var pigBuiltinsL = pigBuiltins.toLowerCase().split(" ").join("() ").split(" ");
var pigBuiltinsC = ("BagSize BinStorage Bloom BuildBloom ConstantSize CubeDimensions DoubleAbs "
+ "DoubleAvg DoubleBase DoubleMax DoubleMin DoubleRound DoubleSum FloatAbs FloatAvg FloatMax "
+ "FloatMin FloatRound FloatSum GenericInvoker IntAbs IntAvg IntMax IntMin IntSum "
+ "InvokeForDouble InvokeForFloat InvokeForInt InvokeForLong InvokeForString Invoker "
+ "IsEmpty JsonLoader JsonMetadata JsonStorage LongAbs LongAvg LongMax LongMin LongSum MapSize "
+ "MonitoredUDF Nondeterministic OutputSchema PigStorage PigStreaming StringConcat StringMax "
+ "StringMin StringSize TextLoader TupleSize Utf8StorageConverter").split(" ").join("() ").split(" ");
function getCompletions(token, context) {
var found = [], start = token.string;
function maybeAdd(str) {
if (str.indexOf(start) == 0 && !arrayContains(found, str)) found.push(str);
}
function gatherCompletions(obj) {
if(obj == ":") {
forEach(pigTypesL, maybeAdd);
}
else {
forEach(pigBuiltinsU, maybeAdd);
forEach(pigBuiltinsL, maybeAdd);
forEach(pigBuiltinsC, maybeAdd);
forEach(pigTypesU, maybeAdd);
forEach(pigTypesL, maybeAdd);
forEach(pigKeywordsU, maybeAdd);
forEach(pigKeywordsL, maybeAdd);
}
}
if (context) {
// If this is a property, see if it belongs to some object we can
// find in the current environment.
var obj = context.pop(), base;
if (obj.className == "pig-word")
base = obj.string;
else if(obj.className == "pig-type")
base = ":" + obj.string;
while (base != null && context.length)
base = base[context.pop().string];
if (base != null) gatherCompletions(base);
}
return found;
}
})();

View File

@ -0,0 +1,90 @@
/* Just enough of CodeMirror to run runMode under node.js */
function splitLines(string){ return string.split(/\r?\n|\r/); };
function StringStream(string) {
this.pos = this.start = 0;
this.string = string;
}
StringStream.prototype = {
eol: function() {return this.pos >= this.string.length;},
sol: function() {return this.pos == 0;},
peek: function() {return this.string.charAt(this.pos) || null;},
next: function() {
if (this.pos < this.string.length)
return this.string.charAt(this.pos++);
},
eat: function(match) {
var ch = this.string.charAt(this.pos);
if (typeof match == "string") var ok = ch == match;
else var ok = ch && (match.test ? match.test(ch) : match(ch));
if (ok) {++this.pos; return ch;}
},
eatWhile: function(match) {
var start = this.pos;
while (this.eat(match)){}
return this.pos > start;
},
eatSpace: function() {
var start = this.pos;
while (/[\s\u00a0]/.test(this.string.charAt(this.pos))) ++this.pos;
return this.pos > start;
},
skipToEnd: function() {this.pos = this.string.length;},
skipTo: function(ch) {
var found = this.string.indexOf(ch, this.pos);
if (found > -1) {this.pos = found; return true;}
},
backUp: function(n) {this.pos -= n;},
column: function() {return this.start;},
indentation: function() {return 0;},
match: function(pattern, consume, caseInsensitive) {
if (typeof pattern == "string") {
function cased(str) {return caseInsensitive ? str.toLowerCase() : str;}
if (cased(this.string).indexOf(cased(pattern), this.pos) == this.pos) {
if (consume !== false) this.pos += pattern.length;
return true;
}
}
else {
var match = this.string.slice(this.pos).match(pattern);
if (match && consume !== false) this.pos += match[0].length;
return match;
}
},
current: function(){return this.string.slice(this.start, this.pos);}
};
exports.StringStream = StringStream;
exports.startState = function(mode, a1, a2) {
return mode.startState ? mode.startState(a1, a2) : true;
};
var modes = exports.modes = {}, mimeModes = exports.mimeModes = {};
exports.defineMode = function(name, mode) { modes[name] = mode; };
exports.defineMIME = function(mime, spec) { mimeModes[mime] = spec; };
exports.getMode = function(options, spec) {
if (typeof spec == "string" && mimeModes.hasOwnProperty(spec))
spec = mimeModes[spec];
if (typeof spec == "string")
var mname = spec, config = {};
else if (spec != null)
var mname = spec.name, config = spec;
var mfactory = modes[mname];
if (!mfactory) throw new Error("Unknown mode: " + spec);
return mfactory(options, config || {});
};
exports.runMode = function(string, modespec, callback) {
var mode = exports.getMode({indentUnit: 2}, modespec);
var lines = splitLines(string), state = exports.startState(mode);
for (var i = 0, e = lines.length; i < e; ++i) {
if (i) callback("\n");
var stream = new exports.StringStream(lines[i]);
while (!stream.eol()) {
var style = mode.token(stream, state);
callback(stream.current(), style, i, stream.start);
stream.start = stream.pos;
}
}
};

View File

@ -0,0 +1,53 @@
CodeMirror.runMode = function(string, modespec, callback, options) {
function esc(str) {
return str.replace(/[<&]/g, function(ch) { return ch == "<" ? "&lt;" : "&amp;"; });
}
var mode = CodeMirror.getMode(CodeMirror.defaults, modespec);
var isNode = callback.nodeType == 1;
var tabSize = (options && options.tabSize) || CodeMirror.defaults.tabSize;
if (isNode) {
var node = callback, accum = [], col = 0;
callback = function(text, style) {
if (text == "\n") {
accum.push("<br>");
col = 0;
return;
}
var escaped = "";
// HTML-escape and replace tabs
for (var pos = 0;;) {
var idx = text.indexOf("\t", pos);
if (idx == -1) {
escaped += esc(text.slice(pos));
col += text.length - pos;
break;
} else {
col += idx - pos;
escaped += esc(text.slice(pos, idx));
var size = tabSize - col % tabSize;
col += size;
for (var i = 0; i < size; ++i) escaped += " ";
pos = idx + 1;
}
}
if (style)
accum.push("<span class=\"cm-" + esc(style) + "\">" + escaped + "</span>");
else
accum.push(escaped);
};
}
var lines = CodeMirror.splitLines(string), state = CodeMirror.startState(mode);
for (var i = 0, e = lines.length; i < e; ++i) {
if (i) callback("\n");
var stream = new CodeMirror.StringStream(lines[i]);
while (!stream.eol()) {
var style = mode.token(stream, state);
callback(stream.current(), style, i, stream.start);
stream.start = stream.pos;
}
}
if (isNode)
node.innerHTML = accum.join("");
};

View File

@ -0,0 +1,118 @@
// Define search commands. Depends on dialog.js or another
// implementation of the openDialog method.
// Replace works a little oddly -- it will do the replace on the next
// Ctrl-G (or whatever is bound to findNext) press. You prevent a
// replace by making sure the match is no longer selected when hitting
// Ctrl-G.
(function() {
function SearchState() {
this.posFrom = this.posTo = this.query = null;
this.marked = [];
}
function getSearchState(cm) {
return cm._searchState || (cm._searchState = new SearchState());
}
function getSearchCursor(cm, query, pos) {
// Heuristic: if the query string is all lowercase, do a case insensitive search.
return cm.getSearchCursor(query, pos, typeof query == "string" && query == query.toLowerCase());
}
function dialog(cm, text, shortText, f) {
if (cm.openDialog) cm.openDialog(text, f);
else f(prompt(shortText, ""));
}
function confirmDialog(cm, text, shortText, fs) {
if (cm.openConfirm) cm.openConfirm(text, fs);
else if (confirm(shortText)) fs[0]();
}
function parseQuery(query) {
var isRE = query.match(/^\/(.*)\/([a-z]*)$/);
return isRE ? new RegExp(isRE[1], isRE[2].indexOf("i") == -1 ? "" : "i") : query;
}
var queryDialog =
'Search: <input type="text" style="width: 10em"/> <span style="color: #888">(Use /re/ syntax for regexp search)</span>';
function doSearch(cm, rev) {
var state = getSearchState(cm);
if (state.query) return findNext(cm, rev);
dialog(cm, queryDialog, "Search for:", function(query) {
cm.operation(function() {
if (!query || state.query) return;
state.query = parseQuery(query);
if (cm.lineCount() < 2000) { // This is too expensive on big documents.
for (var cursor = getSearchCursor(cm, state.query); cursor.findNext();)
state.marked.push(cm.markText(cursor.from(), cursor.to(), "CodeMirror-searching"));
}
state.posFrom = state.posTo = cm.getCursor();
findNext(cm, rev);
});
});
}
function findNext(cm, rev) {cm.operation(function() {
var state = getSearchState(cm);
var cursor = getSearchCursor(cm, state.query, rev ? state.posFrom : state.posTo);
if (!cursor.find(rev)) {
cursor = getSearchCursor(cm, state.query, rev ? {line: cm.lineCount() - 1} : {line: 0, ch: 0});
if (!cursor.find(rev)) return;
}
cm.setSelection(cursor.from(), cursor.to());
state.posFrom = cursor.from(); state.posTo = cursor.to();
});}
function clearSearch(cm) {cm.operation(function() {
var state = getSearchState(cm);
if (!state.query) return;
state.query = null;
for (var i = 0; i < state.marked.length; ++i) state.marked[i].clear();
state.marked.length = 0;
});}
var replaceQueryDialog =
'Replace: <input type="text" style="width: 10em"/> <span style="color: #888">(Use /re/ syntax for regexp search)</span>';
var replacementQueryDialog = 'With: <input type="text" style="width: 10em"/>';
var doReplaceConfirm = "Replace? <button>Yes</button> <button>No</button> <button>Stop</button>";
function replace(cm, all) {
dialog(cm, replaceQueryDialog, "Replace:", function(query) {
if (!query) return;
query = parseQuery(query);
dialog(cm, replacementQueryDialog, "Replace with:", function(text) {
if (all) {
cm.compoundChange(function() { cm.operation(function() {
for (var cursor = getSearchCursor(cm, query); cursor.findNext();) {
if (typeof query != "string") {
var match = cm.getRange(cursor.from(), cursor.to()).match(query);
cursor.replace(text.replace(/\$(\d)/, function(w, i) {return match[i];}));
} else cursor.replace(text);
}
});});
} else {
clearSearch(cm);
var cursor = getSearchCursor(cm, query, cm.getCursor());
function advance() {
var start = cursor.from(), match;
if (!(match = cursor.findNext())) {
cursor = getSearchCursor(cm, query);
if (!(match = cursor.findNext()) ||
(start && cursor.from().line == start.line && cursor.from().ch == start.ch)) return;
}
cm.setSelection(cursor.from(), cursor.to());
confirmDialog(cm, doReplaceConfirm, "Replace?",
[function() {doReplace(match);}, advance]);
}
function doReplace(match) {
cursor.replace(typeof query == "string" ? text :
text.replace(/\$(\d)/, function(w, i) {return match[i];}));
advance();
}
advance();
}
});
});
}
CodeMirror.commands.find = function(cm) {clearSearch(cm); doSearch(cm);};
CodeMirror.commands.findNext = doSearch;
CodeMirror.commands.findPrev = function(cm) {doSearch(cm, true);};
CodeMirror.commands.clearSearch = clearSearch;
CodeMirror.commands.replace = replace;
CodeMirror.commands.replaceAll = function(cm) {replace(cm, true);};
})();

View File

@ -0,0 +1,119 @@
(function(){
function SearchCursor(cm, query, pos, caseFold) {
this.atOccurrence = false; this.cm = cm;
if (caseFold == null && typeof query == "string") caseFold = false;
pos = pos ? cm.clipPos(pos) : {line: 0, ch: 0};
this.pos = {from: pos, to: pos};
// The matches method is filled in based on the type of query.
// It takes a position and a direction, and returns an object
// describing the next occurrence of the query, or null if no
// more matches were found.
if (typeof query != "string") { // Regexp match
if (!query.global) query = new RegExp(query.source, query.ignoreCase ? "ig" : "g");
this.matches = function(reverse, pos) {
if (reverse) {
query.lastIndex = 0;
var line = cm.getLine(pos.line).slice(0, pos.ch), match = query.exec(line), start = 0;
while (match) {
start += match.index + 1;
line = line.slice(start);
query.lastIndex = 0;
var newmatch = query.exec(line);
if (newmatch) match = newmatch;
else break;
}
start--;
} else {
query.lastIndex = pos.ch;
var line = cm.getLine(pos.line), match = query.exec(line),
start = match && match.index;
}
if (match)
return {from: {line: pos.line, ch: start},
to: {line: pos.line, ch: start + match[0].length},
match: match};
};
} else { // String query
if (caseFold) query = query.toLowerCase();
var fold = caseFold ? function(str){return str.toLowerCase();} : function(str){return str;};
var target = query.split("\n");
// Different methods for single-line and multi-line queries
if (target.length == 1)
this.matches = function(reverse, pos) {
var line = fold(cm.getLine(pos.line)), len = query.length, match;
if (reverse ? (pos.ch >= len && (match = line.lastIndexOf(query, pos.ch - len)) != -1)
: (match = line.indexOf(query, pos.ch)) != -1)
return {from: {line: pos.line, ch: match},
to: {line: pos.line, ch: match + len}};
};
else
this.matches = function(reverse, pos) {
var ln = pos.line, idx = (reverse ? target.length - 1 : 0), match = target[idx], line = fold(cm.getLine(ln));
var offsetA = (reverse ? line.indexOf(match) + match.length : line.lastIndexOf(match));
if (reverse ? offsetA >= pos.ch || offsetA != match.length
: offsetA <= pos.ch || offsetA != line.length - match.length)
return;
for (;;) {
if (reverse ? !ln : ln == cm.lineCount() - 1) return;
line = fold(cm.getLine(ln += reverse ? -1 : 1));
match = target[reverse ? --idx : ++idx];
if (idx > 0 && idx < target.length - 1) {
if (line != match) return;
else continue;
}
var offsetB = (reverse ? line.lastIndexOf(match) : line.indexOf(match) + match.length);
if (reverse ? offsetB != line.length - match.length : offsetB != match.length)
return;
var start = {line: pos.line, ch: offsetA}, end = {line: ln, ch: offsetB};
return {from: reverse ? end : start, to: reverse ? start : end};
}
};
}
}
SearchCursor.prototype = {
findNext: function() {return this.find(false);},
findPrevious: function() {return this.find(true);},
find: function(reverse) {
var self = this, pos = this.cm.clipPos(reverse ? this.pos.from : this.pos.to);
function savePosAndFail(line) {
var pos = {line: line, ch: 0};
self.pos = {from: pos, to: pos};
self.atOccurrence = false;
return false;
}
for (;;) {
if (this.pos = this.matches(reverse, pos)) {
this.atOccurrence = true;
return this.pos.match || true;
}
if (reverse) {
if (!pos.line) return savePosAndFail(0);
pos = {line: pos.line-1, ch: this.cm.getLine(pos.line-1).length};
}
else {
var maxLine = this.cm.lineCount();
if (pos.line == maxLine - 1) return savePosAndFail(maxLine);
pos = {line: pos.line+1, ch: 0};
}
}
},
from: function() {if (this.atOccurrence) return this.pos.from;},
to: function() {if (this.atOccurrence) return this.pos.to;},
replace: function(newText) {
var self = this;
if (this.atOccurrence)
self.pos.to = this.cm.replaceRange(newText, self.pos.from, self.pos.to);
}
};
CodeMirror.defineExtension("getSearchCursor", function(query, pos, caseFold) {
return new SearchCursor(this, query, pos, caseFold);
});
})();

View File

@ -0,0 +1,16 @@
.CodeMirror-completions {
position: absolute;
z-index: 10;
overflow: hidden;
-webkit-box-shadow: 2px 3px 5px rgba(0,0,0,.2);
-moz-box-shadow: 2px 3px 5px rgba(0,0,0,.2);
box-shadow: 2px 3px 5px rgba(0,0,0,.2);
}
.CodeMirror-completions select {
background: #fafafa;
outline: none;
border: none;
padding: 0;
margin: 0;
font-family: monospace;
}

View File

@ -0,0 +1,102 @@
(function() {
CodeMirror.simpleHint = function(editor, getHints, givenOptions) {
// Determine effective options based on given values and defaults.
var options = {}, defaults = CodeMirror.simpleHint.defaults;
for (var opt in defaults)
if (defaults.hasOwnProperty(opt))
options[opt] = (givenOptions && givenOptions.hasOwnProperty(opt) ? givenOptions : defaults)[opt];
function collectHints(previousToken) {
// We want a single cursor position.
if (editor.somethingSelected()) return;
var tempToken = editor.getTokenAt(editor.getCursor());
// Don't show completions if token has changed and the option is set.
if (options.closeOnTokenChange && previousToken != null &&
(tempToken.start != previousToken.start || tempToken.className != previousToken.className)) {
return;
}
var result = getHints(editor);
if (!result || !result.list.length) return;
var completions = result.list;
function insert(str) {
editor.replaceRange(str, result.from, result.to);
}
// When there is only one completion, use it directly.
if (options.completeSingle && completions.length == 1) {
insert(completions[0]);
return true;
}
// Build the select widget
var complete = document.createElement("div");
complete.className = "CodeMirror-completions";
var sel = complete.appendChild(document.createElement("select"));
// Opera doesn't move the selection when pressing up/down in a
// multi-select, but it does properly support the size property on
// single-selects, so no multi-select is necessary.
if (!window.opera) sel.multiple = true;
for (var i = 0; i < completions.length; ++i) {
var opt = sel.appendChild(document.createElement("option"));
opt.appendChild(document.createTextNode(completions[i]));
}
sel.firstChild.selected = true;
sel.size = Math.min(10, completions.length);
var pos = options.alignWithWord ? editor.charCoords(result.from) : editor.cursorCoords();
complete.style.left = pos.x + "px";
complete.style.top = pos.yBot + "px";
document.body.appendChild(complete);
// If we're at the edge of the screen, then we want the menu to appear on the left of the cursor.
var winW = window.innerWidth || Math.max(document.body.offsetWidth, document.documentElement.offsetWidth);
if(winW - pos.x < sel.clientWidth)
complete.style.left = (pos.x - sel.clientWidth) + "px";
// Hack to hide the scrollbar.
if (completions.length <= 10)
complete.style.width = (sel.clientWidth - 1) + "px";
var done = false;
function close() {
if (done) return;
done = true;
complete.parentNode.removeChild(complete);
}
function pick() {
insert(completions[sel.selectedIndex]);
close();
setTimeout(function(){editor.focus();}, 50);
}
CodeMirror.connect(sel, "blur", close);
CodeMirror.connect(sel, "keydown", function(event) {
var code = event.keyCode;
// Enter
if (code == 13) {CodeMirror.e_stop(event); pick();}
// Escape
else if (code == 27) {CodeMirror.e_stop(event); close(); editor.focus();}
else if (code != 38 && code != 40 && code != 33 && code != 34 && !CodeMirror.isModifierKey(event)) {
close(); editor.focus();
// Pass the event to the CodeMirror instance so that it can handle things like backspace properly.
editor.triggerOnKeyDown(event);
// Don't show completions if the code is backspace and the option is set.
if (!options.closeOnBackspace || code != 8) {
setTimeout(function(){collectHints(tempToken);}, 50);
}
}
});
CodeMirror.connect(sel, "dblclick", pick);
sel.focus();
// Opera sometimes ignores focusing a freshly created node
if (window.opera) setTimeout(function(){if (!done) sel.focus();}, 100);
return true;
}
return collectHints();
};
CodeMirror.simpleHint.defaults = {
closeOnBackspace: true,
closeOnTokenChange: false,
completeSingle: true,
alignWithWord: true
};
})();

View File

@ -0,0 +1,137 @@
(function() {
CodeMirror.xmlHints = [];
CodeMirror.xmlHint = function(cm, simbol) {
if(simbol.length > 0) {
var cursor = cm.getCursor();
cm.replaceSelection(simbol);
cursor = {line: cursor.line, ch: cursor.ch + 1};
cm.setCursor(cursor);
}
// dirty hack for simple-hint to receive getHint event on space
var getTokenAt = editor.getTokenAt;
editor.getTokenAt = function() { return 'disabled'; };
CodeMirror.simpleHint(cm, getHint);
editor.getTokenAt = getTokenAt;
};
var getHint = function(cm) {
var cursor = cm.getCursor();
if (cursor.ch > 0) {
var text = cm.getRange({line: 0, ch: 0}, cursor);
var typed = '';
var simbol = '';
for(var i = text.length - 1; i >= 0; i--) {
if(text[i] == ' ' || text[i] == '<') {
simbol = text[i];
break;
}
else {
typed = text[i] + typed;
}
}
text = text.slice(0, text.length - typed.length);
var path = getActiveElement(cm, text) + simbol;
var hints = CodeMirror.xmlHints[path];
if(typeof hints === 'undefined')
hints = [''];
else {
hints = hints.slice(0);
for (var i = hints.length - 1; i >= 0; i--) {
if(hints[i].indexOf(typed) != 0)
hints.splice(i, 1);
}
}
return {
list: hints,
from: { line: cursor.line, ch: cursor.ch - typed.length },
to: cursor
};
};
};
var getActiveElement = function(codeMirror, text) {
var element = '';
if(text.length >= 0) {
var regex = new RegExp('<([^!?][^\\s/>]*).*?>', 'g');
var matches = [];
var match;
while ((match = regex.exec(text)) != null) {
matches.push({
tag: match[1],
selfclose: (match[0].slice(match[0].length - 2) === '/>')
});
}
for (var i = matches.length - 1, skip = 0; i >= 0; i--) {
var item = matches[i];
if (item.tag[0] == '/')
{
skip++;
}
else if (item.selfclose == false)
{
if (skip > 0)
{
skip--;
}
else
{
element = '<' + item.tag + '>' + element;
}
}
}
element += getOpenTag(text);
}
return element;
};
var getOpenTag = function(text) {
var open = text.lastIndexOf('<');
var close = text.lastIndexOf('>');
if (close < open)
{
text = text.slice(open);
if(text != '<') {
var space = text.indexOf(' ');
if(space < 0)
space = text.indexOf('\t');
if(space < 0)
space = text.indexOf('\n');
if (space < 0)
space = text.length;
return text.slice(0, space);
}
}
return '';
};
})();

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,917 @@
;(function($) {
/*
* ui.dropdownchecklist
*
* Copyright (c) 2008-2010 Adrian Tosca, Copyright (c) 2010-2011 Ittrium LLC
* Dual licensed under the MIT (MIT-LICENSE.txt) OR GPL (GPL-LICENSE.txt) licenses.
*
*/
// The dropdown check list jQuery plugin transforms a regular select html element into a dropdown check list.
$.widget("ui.dropdownchecklist", {
// Some globlals
// $.ui.dropdownchecklist.gLastOpened - keeps track of last opened dropdowncheck list so we can close it
// $.ui.dropdownchecklist.gIDCounter - simple counter to provide a unique ID as needed
version: function() {
alert('DropDownCheckList v1.4');
},
// Creates the drop container that keeps the items and appends it to the document
_appendDropContainer: function( controlItem ) {
var wrapper = $("<div/>");
// the container is wrapped in a div
wrapper.addClass("ui-dropdownchecklist ui-dropdownchecklist-dropcontainer-wrapper");
wrapper.addClass("ui-widget");
// assign an id
wrapper.attr("id",controlItem.attr("id") + '-ddw');
// initially positioned way off screen to prevent it from displaying
// NOTE absolute position to enable width/height calculation
wrapper.css({ position: 'absolute', left: "-33000px", top: "-33000px" });
var container = $("<div/>"); // the actual container
container.addClass("ui-dropdownchecklist-dropcontainer ui-widget-content");
container.css("overflow-y", "auto");
wrapper.append(container);
// insert the dropdown after the master control to try to keep the tab order intact
// if you just add it to the end, tabbing out of the drop down takes focus off the page
// @todo 22Sept2010 - check if size calculation is thrown off if the parent of the
// selector is hidden. We may need to add it to the end of the document here,
// calculate the size, and then move it back into proper position???
//$(document.body).append(wrapper);
wrapper.insertAfter(controlItem);
// flag that tells if the drop container is shown or not
wrapper.isOpen = false;
return wrapper;
},
// Look for browser standard 'open' on a closed selector
_isDropDownKeyShortcut: function(e,keycode) {
return e.altKey && ($.ui.keyCode.DOWN == keycode);// Alt + Down Arrow
},
// Look for key that will tell us to close the open dropdown
_isDropDownCloseKey: function(e,keycode) {
return ($.ui.keyCode.ESCAPE == keycode) || ($.ui.keyCode.ENTER == keycode);
},
// Handler to change the active focus based on a keystroke, moving some count of
// items from the element that has the current focus
_keyFocusChange: function(target,delta,limitToItems) {
// Find item with current focus
var focusables = $(":focusable");
var index = focusables.index(target);
if ( index >= 0 ) {
index += delta;
if ( limitToItems ) {
// Bound change to list of input elements
var allCheckboxes = this.dropWrapper.find("input:not([disabled])");
var firstIndex = focusables.index(allCheckboxes.get(0));
var lastIndex = focusables.index(allCheckboxes.get(allCheckboxes.length-1));
if ( index < firstIndex ) {
index = lastIndex;
} else if ( index > lastIndex ) {
index = firstIndex;
}
}
focusables.get(index).focus();
}
},
// Look for navigation, open, close (wired to keyup)
_handleKeyboard: function(e) {
var self = this;
var keyCode = (e.keyCode || e.which);
if (!self.dropWrapper.isOpen && self._isDropDownKeyShortcut(e, keyCode)) {
// Key command to open the dropdown
e.stopImmediatePropagation();
self._toggleDropContainer(true);
} else if (self.dropWrapper.isOpen && self._isDropDownCloseKey(e, keyCode)) {
// Key command to close the dropdown (but we retain focus in the control)
e.stopImmediatePropagation();
self._toggleDropContainer(false);
self.controlSelector.focus();
} else if (self.dropWrapper.isOpen
&& (e.target.type == 'checkbox')
&& ((keyCode == $.ui.keyCode.DOWN) || (keyCode == $.ui.keyCode.UP)) ) {
// Up/Down to cycle throught the open items
e.stopImmediatePropagation();
self._keyFocusChange(e.target, (keyCode == $.ui.keyCode.DOWN) ? 1 : -1, true);
} else if (self.dropWrapper.isOpen && (keyCode == $.ui.keyCode.TAB) ) {
// I wanted to adjust normal 'tab' processing here, but research indicates
// that TAB key processing is NOT a cancelable event. You have to use a timer
// hack to pull the focus back to where you want it after browser tab
// processing completes. Not going to work for us.
//e.stopImmediatePropagation();
//self._keyFocusChange(e.target, (e.shiftKey) ? -1 : 1, true);
}
},
// Look for change of focus
_handleFocus: function(e,focusIn,forDropdown) {
var self = this;
if (forDropdown && !self.dropWrapper.isOpen) {
// if the focus changes when the control is NOT open, mark it to show where the focus is/is not
e.stopImmediatePropagation();
if (focusIn) {
self.controlSelector.addClass("ui-state-hover");
if ($.ui.dropdownchecklist.gLastOpened != null) {
$.ui.dropdownchecklist.gLastOpened._toggleDropContainer( false );
}
} else {
self.controlSelector.removeClass("ui-state-hover");
}
} else if (!forDropdown && !focusIn) {
// The dropdown is open, and an item (NOT the dropdown) has just lost the focus.
// we really need a reliable method to see who has the focus as we process the blur,
// but that mechanism does not seem to exist. Instead we rely on a delay before
// posting the blur, with a focus event cancelling it before the delay expires.
if ( e != null ) { e.stopImmediatePropagation(); }
self.controlSelector.removeClass("ui-state-hover");
self._toggleDropContainer( false );
}
},
// Clear the pending change of focus, which keeps us 'in' the control
_cancelBlur: function(e) {
var self = this;
if (self.blurringItem != null) {
clearTimeout(self.blurringItem);
self.blurringItem = null;
}
},
// Creates the control that will replace the source select and appends it to the document
// The control resembles a regular select with single selection
_appendControl: function() {
var self = this, sourceSelect = this.sourceSelect, options = this.options;
// the control is wrapped in a basic container
// inline-block at this level seems to give us better size control
var wrapper = $("<span/>");
wrapper.addClass("ui-dropdownchecklist ui-dropdownchecklist-selector-wrapper ui-widget");
wrapper.css( { display: "inline-block", cursor: "default", overflow: "hidden" } );
// assign an ID
var baseID = sourceSelect.attr("id");
if ((baseID == null) || (baseID == "")) {
baseID = "ddcl-" + $.ui.dropdownchecklist.gIDCounter++;
} else {
baseID = "ddcl-" + baseID;
}
wrapper.attr("id",baseID);
// the actual control which you can style
// inline-block needed to enable 'width' but has interesting problems cross browser
var control = $("<span/>");
control.addClass("ui-dropdownchecklist-selector ui-state-default");
control.css( { display: "inline-block", overflow: "hidden", 'white-space': 'nowrap'} );
// Setting a tab index means we are interested in the tab sequence
var tabIndex = sourceSelect.attr("tabIndex");
if ( tabIndex == null ) {
tabIndex = 0;
} else {
tabIndex = parseInt(tabIndex);
if ( tabIndex < 0 ) {
tabIndex = 0;
}
}
control.attr("tabIndex", tabIndex);
control.keyup(function(e) {self._handleKeyboard(e);});
control.focus(function(e) {self._handleFocus(e,true,true);});
control.blur(function(e) {self._handleFocus(e,false,true);});
wrapper.append(control);
// the optional icon (which is inherently a block) which we can float
if (options.icon != null) {
var iconPlacement = (options.icon.placement == null) ? "left" : options.icon.placement;
var anIcon = $("<div/>");
anIcon.addClass("ui-icon");
anIcon.addClass( (options.icon.toOpen != null) ? options.icon.toOpen : "ui-icon-triangle-1-e");
anIcon.css({ 'float': iconPlacement });
control.append(anIcon);
}
// the text container keeps the control text that is built from the selected (checked) items
// inline-block needed to prevent long text from wrapping to next line when icon is active
var textContainer = $("<span/>");
textContainer.addClass("ui-dropdownchecklist-text");
textContainer.css( { display: "inline-block", 'white-space': "nowrap", overflow: "hidden" } );
control.append(textContainer);
// add the hover styles to the control
wrapper.hover(
function() {
if (!self.disabled) {
control.addClass("ui-state-hover");
}
}
, function() {
if (!self.disabled) {
control.removeClass("ui-state-hover");
}
}
);
// clicking on the control toggles the drop container
wrapper.click(function(event) {
if (!self.disabled) {
event.stopImmediatePropagation();
self._toggleDropContainer( !self.dropWrapper.isOpen );
}
});
wrapper.insertAfter(sourceSelect);
// Watch for a window resize and adjust the control if open
$(window).resize(function() {
if (!self.disabled && self.dropWrapper.isOpen) {
// Reopen yourself to get the position right
self._toggleDropContainer(true);
}
});
return wrapper;
},
// Creates a drop item that coresponds to an option element in the source select
_createDropItem: function(index, tabIndex, value, text, optCss, checked, disabled, indent) {
var self = this, options = this.options, sourceSelect = this.sourceSelect, controlWrapper = this.controlWrapper;
// the item contains a div that contains a checkbox input and a lable for the text
// the div
var item = $("<div/>");
item.addClass("ui-dropdownchecklist-item");
item.css({'white-space': "nowrap"});
var checkedString = checked ? ' checked="checked"' : '';
var classString = disabled ? ' class="inactive"' : ' class="active"';
// generated id must be a bit unique to keep from colliding
var idBase = controlWrapper.attr("id");
var id = idBase + '-i' + index;
var checkBox;
// all items start out disabled to keep them out of the tab order
if (self.isMultiple) { // the checkbox
checkBox = $('<input disabled type="checkbox" id="' + id + '"' + checkedString + classString + ' tabindex="' + tabIndex + '" />');
} else { // the radiobutton
checkBox = $('<input disabled type="radio" id="' + id + '" name="' + idBase + '"' + checkedString + classString + ' tabindex="' + tabIndex + '" />');
}
checkBox = checkBox.attr("index", index).val(value);
item.append(checkBox);
// the text
var label = $("<label for=" + id + "/>");
label.addClass("ui-dropdownchecklist-text");
if ( optCss != null ) label.attr('style',optCss);
label.css({ cursor: "default" });
label.html(text);
if (indent) {
item.addClass("ui-dropdownchecklist-indent");
}
item.addClass("ui-state-default");
if (disabled) {
item.addClass("ui-state-disabled");
}
label.click(function(e) {e.stopImmediatePropagation();});
item.append(label);
// active items display themselves with hover
item.hover(
function(e) {
var anItem = $(this);
if (!anItem.hasClass("ui-state-disabled")) { anItem.addClass("ui-state-hover"); }
}
, function(e) {
var anItem = $(this);
anItem.removeClass("ui-state-hover");
}
);
// clicking on the checkbox synchronizes the source select
checkBox.click(function(e) {
var aCheckBox = $(this);
e.stopImmediatePropagation();
if (aCheckBox.hasClass("active") ) {
// Active checkboxes take active action
var callback = self.options.onItemClick;
if ($.isFunction(callback)) try {
callback.call(self,aCheckBox,sourceSelect.get(0));
} catch (ex) {
// reject the change on any error
aCheckBox.prop("checked",!aCheckBox.prop("checked"));
self._syncSelected(aCheckBox);
return;
}
self._syncSelected(aCheckBox);
self.sourceSelect.trigger("change", 'ddcl_internal');
if (!self.isMultiple && options.closeRadioOnClick) {
self._toggleDropContainer(false);
}
}
});
// we are interested in the focus leaving the check box
// but we need to detect the focus leaving one check box but
// entering another. There is no reliable way to detect who
// received the focus on a blur, so post the blur in the future,
// knowing we will cancel it if we capture the focus in a timely manner
// 23Sept2010 - unfortunately, IE 7+ and Chrome like to post a blur
// event to the current item with focus when the user
// clicks in the scroll bar. So if you have a scrollable
// dropdown with focus on an item, clicking in the scroll
// will close the drop down.
// I have no solution for blur processing at this time.
/*********
var timerFunction = function(){
// I had a hell of a time getting setTimeout to fire this, do not try to
// define it within the blur function
try { self._handleFocus(null,false,false); } catch(ex){ alert('timer failed: '+ex);}
};
checkBox.blur(function(e) {
self.blurringItem = setTimeout( timerFunction, 200 );
});
checkBox.focus(function(e) {self._cancelBlur();});
**********/
// check/uncheck the item on clicks on the entire item div
item.click(function(e) {
var anItem = $(this);
e.stopImmediatePropagation();
if (!anItem.hasClass("ui-state-disabled") ) {
// check/uncheck the underlying control
var aCheckBox = anItem.find("input");
var checked = aCheckBox.prop("checked");
aCheckBox.prop("checked", !checked);
var callback = self.options.onItemClick;
if ($.isFunction(callback)) try {
callback.call(self,aCheckBox,sourceSelect.get(0));
} catch (ex) {
// reject the change on any error
aCheckBox.prop("checked",checked);
self._syncSelected(aCheckBox);
return;
}
self._syncSelected(aCheckBox);
self.sourceSelect.trigger("change", 'ddcl_internal');
if (!checked && !self.isMultiple && options.closeRadioOnClick) {
self._toggleDropContainer(false);
}
} else {
// retain the focus even if disabled
anItem.focus();
self._cancelBlur();
}
});
// do not let the focus wander around
item.focus(function(e) {
var anItem = $(this);
e.stopImmediatePropagation();
});
item.keyup(function(e) {self._handleKeyboard(e);});
return item;
},
_createGroupItem: function(text,disabled) {
var self = this;
var group = $("<div />");
group.addClass("ui-dropdownchecklist-group ui-widget-header");
if (disabled) {
group.addClass("ui-state-disabled");
}
group.css({'white-space': "nowrap"});
var label = $("<span/>");
label.addClass("ui-dropdownchecklist-text");
label.css( { cursor: "default" });
label.text(text);
group.append(label);
// anything interesting when you click the group???
group.click(function(e) {
var aGroup= $(this);
e.stopImmediatePropagation();
// retain the focus even if no action is taken
aGroup.focus();
self._cancelBlur();
});
// do not let the focus wander around
group.focus(function(e) {
var aGroup = $(this);
e.stopImmediatePropagation();
});
return group;
},
_createCloseItem: function(text) {
var self = this;
var closeItem = $("<div />");
closeItem.addClass("ui-state-default ui-dropdownchecklist-close ui-dropdownchecklist-item");
closeItem.css({'white-space': 'nowrap', 'text-align': 'right'});
var label = $("<span/>");
label.addClass("ui-dropdownchecklist-text");
label.css( { cursor: "default" });
label.html(text);
closeItem.append(label);
// close the control on click
closeItem.click(function(e) {
var aGroup= $(this);
e.stopImmediatePropagation();
// retain the focus even if no action is taken
aGroup.focus();
self._toggleDropContainer( false );
});
closeItem.hover(
function(e) { $(this).addClass("ui-state-hover"); }
, function(e) { $(this).removeClass("ui-state-hover"); }
);
// do not let the focus wander around
closeItem.focus(function(e) {
var aGroup = $(this);
e.stopImmediatePropagation();
});
return closeItem;
},
// Creates the drop items and appends them to the drop container
// Also calculates the size needed by the drop container and returns it
_appendItems: function() {
var self = this, config = this.options, sourceSelect = this.sourceSelect, dropWrapper = this.dropWrapper;
var dropContainerDiv = dropWrapper.find(".ui-dropdownchecklist-dropcontainer");
sourceSelect.children().each(function(index) { // when the select has groups
var opt = $(this);
if (opt.is("option")) {
self._appendOption(opt, dropContainerDiv, index, false, false);
} else if (opt.is("optgroup")) {
var disabled = opt.prop("disabled");
var text = opt.attr("label");
if (text != "") {
var group = self._createGroupItem(text,disabled);
dropContainerDiv.append(group);
}
self._appendOptions(opt, dropContainerDiv, index, true, disabled);
}
});
if ( config.explicitClose != null ) {
var closeItem = self._createCloseItem(config.explicitClose);
dropContainerDiv.append(closeItem);
}
var divWidth = dropContainerDiv.outerWidth();
var divHeight = dropContainerDiv.outerHeight();
return { width: divWidth, height: divHeight };
},
_appendOptions: function(parent, container, parentIndex, indent, forceDisabled) {
var self = this;
parent.children("option").each(function(index) {
var option = $(this);
var childIndex = (parentIndex + "." + index);
self._appendOption(option, container, childIndex, indent, forceDisabled);
});
},
_appendOption: function(option, container, index, indent, forceDisabled) {
var self = this;
// Note that the browsers destroy any html structure within the OPTION
var text = option.html();
if ( (text != null) && (text != '') ) {
var value = option.val();
var optCss = option.attr('style');
var selected = option.prop("selected");
var disabled = (forceDisabled || option.prop("disabled"));
// Use the same tab index as the selector replacement
var tabIndex = self.controlSelector.attr("tabindex");
var item = self._createDropItem(index, tabIndex, value, text, optCss, selected, disabled, indent);
container.append(item);
}
},
// Synchronizes the items checked and the source select
// When firstItemChecksAll option is active also synchronizes the checked items
// senderCheckbox parameters is the checkbox input that generated the synchronization
_syncSelected: function(senderCheckbox) {
var self = this, options = this.options, sourceSelect = this.sourceSelect, dropWrapper = this.dropWrapper;
var selectOptions = sourceSelect.get(0).options;
var allCheckboxes = dropWrapper.find("input.active");
if (options.firstItemChecksAll == 'exclusive') {
if ((senderCheckbox == null) && $(selectOptions[0]).prop("selected") ) {
// Initialization call with first item active
allCheckboxes.prop("checked", false);
$(allCheckboxes[0]).prop("checked", true);
} else if ((senderCheckbox != null) && (senderCheckbox.attr("index") == 0)) {
// Action on the first, so all other checkboxes NOT active
var firstIsActive = senderCheckbox.prop("checked");
allCheckboxes.prop("checked", false);
$(allCheckboxes[0]).prop("checked", firstIsActive);
} else {
// check the first checkbox if all the other checkboxes are checked
var allChecked = true;
var firstCheckbox = null;
allCheckboxes.each(function(index) {
if (index > 0) {
var checked = $(this).prop("checked");
if (!checked) { allChecked = false; }
} else {
firstCheckbox = $(this);
}
});
if ( firstCheckbox != null ) {
if ( allChecked ) {
// when all are checked, only the first left checked
allCheckboxes.prop("checked", false);
}
firstCheckbox.prop("checked", allChecked );
}
}
} else if (options.firstItemChecksAll) {
if ((senderCheckbox == null) && $(selectOptions[0]).prop("selected") ) {
// Initialization call with first item active so force all to be active
allCheckboxes.prop("checked", true);
} else if ((senderCheckbox != null) && (senderCheckbox.attr("index") == 0)) {
// Check all checkboxes if the first one is checked
allCheckboxes.prop("checked", senderCheckbox.prop("checked"));
} else {
// check the first checkbox if all the other checkboxes are checked
var allChecked = true;
var firstCheckbox = null;
allCheckboxes.each(function(index) {
if (index > 0) {
var checked = $(this).prop("checked");
if (!checked) { allChecked = false; }
} else {
firstCheckbox = $(this);
}
});
if ( firstCheckbox != null ) {
firstCheckbox.prop("checked", allChecked );
}
}
}
// do the actual synch with the source select
var empties = 0;
allCheckboxes = dropWrapper.find("input");
allCheckboxes.each(function(index) {
var anOption = $(selectOptions[index + empties]);
var optionText = anOption.html();
if ( (optionText == null) || (optionText == '') ) {
empties += 1;
anOption = $(selectOptions[index + empties]);
}
anOption.prop("selected", $(this).prop("checked"));
});
// update the text shown in the control
self._updateControlText();
// Ensure the focus stays pointing where the user is working
if ( senderCheckbox != null) { senderCheckbox.focus(); }
},
_sourceSelectChangeHandler: function(event) {
var self = this, dropWrapper = this.dropWrapper;
dropWrapper.find("input").val(self.sourceSelect.val());
// update the text shown in the control
self._updateControlText();
},
// Updates the text shown in the control depending on the checked (selected) items
_updateControlText: function() {
var self = this, sourceSelect = this.sourceSelect, options = this.options, controlWrapper = this.controlWrapper;
var firstOption = sourceSelect.find("option:first");
var selectOptions = sourceSelect.find("option");
var text = self._formatText(selectOptions, options.firstItemChecksAll, firstOption);
var controlLabel = controlWrapper.find(".ui-dropdownchecklist-text");
controlLabel.html(text);
// the attribute needs naked text, not html
controlLabel.attr("title", controlLabel.text());
},
// Formats the text that is shown in the control
_formatText: function(selectOptions, firstItemChecksAll, firstOption) {
var text;
if ( $.isFunction(this.options.textFormatFunction) ) {
// let the callback do the formatting, but do not allow it to fail
try {
text = this.options.textFormatFunction(selectOptions);
} catch(ex) {
alert( 'textFormatFunction failed: ' + ex );
}
} else if (firstItemChecksAll && (firstOption != null) && firstOption.prop("selected")) {
// just set the text from the first item
text = firstOption.html();
} else {
// concatenate the text from the checked items
text = "";
selectOptions.each(function() {
if ($(this).prop("selected")) {
if ( text != "" ) { text += ", "; }
/* NOTE use of .html versus .text, which can screw up ampersands for IE */
var optCss = $(this).attr('style');
var tempspan = $('<span/>');
tempspan.html( $(this).html() );
if ( optCss == null ) {
text += tempspan.html();
} else {
tempspan.attr('style',optCss);
text += $("<span/>").append(tempspan).html();
}
}
});
if ( text == "" ) {
text = (this.options.emptyText != null) ? this.options.emptyText : "&nbsp;";
}
}
return text;
},
// Shows and hides the drop container
_toggleDropContainer: function( makeOpen ) {
var self = this;
// hides the last shown drop container
var hide = function(instance) {
if ((instance != null) && instance.dropWrapper.isOpen ){
instance.dropWrapper.isOpen = false;
$.ui.dropdownchecklist.gLastOpened = null;
var config = instance.options;
instance.dropWrapper.css({
top: "-33000px",
left: "-33000px"
});
var aControl = instance.controlSelector;
aControl.removeClass("ui-state-active");
aControl.removeClass("ui-state-hover");
var anIcon = instance.controlWrapper.find(".ui-icon");
if ( anIcon.length > 0 ) {
anIcon.removeClass( (config.icon.toClose != null) ? config.icon.toClose : "ui-icon-triangle-1-s");
anIcon.addClass( (config.icon.toOpen != null) ? config.icon.toOpen : "ui-icon-triangle-1-e");
}
$(document).unbind("click", hide);
// keep the items out of the tab order by disabling them
instance.dropWrapper.find("input.active").prop("disabled",true);
// the following blur just does not fire??? because it is hidden??? because it does not have focus???
//instance.sourceSelect.trigger("blur");
//instance.sourceSelect.triggerHandler("blur");
if($.isFunction(config.onComplete)) { try {
config.onComplete.call(instance,instance.sourceSelect.get(0));
} catch(ex) {
alert( 'callback failed: ' + ex );
}}
}
};
// shows the given drop container instance
var show = function(instance) {
if ( !instance.dropWrapper.isOpen ) {
instance.dropWrapper.isOpen = true;
$.ui.dropdownchecklist.gLastOpened = instance;
var config = instance.options;
/**** Issue127 (and the like) to correct positioning when parent element is relative
**** This positioning only worked with simple, non-relative parent position
instance.dropWrapper.css({
top: instance.controlWrapper.offset().top + instance.controlWrapper.outerHeight() + "px",
left: instance.controlWrapper.offset().left + "px"
});
****/
if ((config.positionHow == null) || (config.positionHow == 'absolute')) {
/** Floats above subsequent content, but does NOT scroll */
instance.dropWrapper.css({
position: 'absolute'
, top: instance.controlWrapper.position().top + instance.controlWrapper.outerHeight() + "px"
, left: instance.controlWrapper.position().left + "px"
});
} else if (config.positionHow == 'relative') {
/** Scrolls with the parent but does NOT float above subsequent content */
instance.dropWrapper.css({
position: 'relative'
, top: "0px"
, left: "0px"
});
}
var zIndex = 0;
if (config.zIndex == null) {
var ancestorsZIndexes = instance.controlWrapper.parents().map(
function() {
var zIndex = $(this).css("z-index");
return isNaN(zIndex) ? 0 : zIndex; }
).get();
var parentZIndex = Math.max.apply(Math, ancestorsZIndexes);
if ( parentZIndex >= 0) zIndex = parentZIndex+1;
} else {
/* Explicit set from the optins */
zIndex = parseInt(config.zIndex);
}
if (zIndex > 0) {
instance.dropWrapper.css( { 'z-index': zIndex } );
}
var aControl = instance.controlSelector;
aControl.addClass("ui-state-active");
aControl.removeClass("ui-state-hover");
var anIcon = instance.controlWrapper.find(".ui-icon");
if ( anIcon.length > 0 ) {
anIcon.removeClass( (config.icon.toOpen != null) ? config.icon.toOpen : "ui-icon-triangle-1-e");
anIcon.addClass( (config.icon.toClose != null) ? config.icon.toClose : "ui-icon-triangle-1-s");
}
$(document).bind("click", function(e) {hide(instance);} );
// insert the items back into the tab order by enabling all active ones
var activeItems = instance.dropWrapper.find("input.active");
activeItems.prop("disabled",false);
// we want the focus on the first active input item
var firstActiveItem = activeItems.get(0);
if ( firstActiveItem != null ) {
firstActiveItem.focus();
}
}
};
if ( makeOpen ) {
hide($.ui.dropdownchecklist.gLastOpened);
show(self);
} else {
hide(self);
}
},
// Set the size of the control and of the drop container
_setSize: function(dropCalculatedSize) {
var options = this.options, dropWrapper = this.dropWrapper, controlWrapper = this.controlWrapper;
// use the width from config options if set, otherwise set the same width as the drop container
var controlWidth = dropCalculatedSize.width;
if (options.width != null) {
controlWidth = parseInt(options.width);
} else if (options.minWidth != null) {
var minWidth = parseInt(options.minWidth);
// if the width is too small (usually when there are no items) set a minimum width
if (controlWidth < minWidth) {
controlWidth = minWidth;
}
}
var control = this.controlSelector;
control.css({ width: controlWidth + "px" });
// if we size the text, then Firefox places icons to the right properly
// and we do not wrap on long lines
var controlText = control.find(".ui-dropdownchecklist-text");
var controlIcon = control.find(".ui-icon");
if ( controlIcon != null ) {
// Must be an inner/outer/border problem, but IE6 needs an extra bit of space,
// otherwise you can get text pushed down into a second line when icons are active
controlWidth -= (controlIcon.outerWidth() + 4);
controlText.css( { width: controlWidth + "px" } );
}
// Account for padding, borders, etc
controlWidth = controlWrapper.outerWidth();
// the drop container height can be set from options
var maxDropHeight = (options.maxDropHeight != null)
? parseInt(options.maxDropHeight)
: -1;
var dropHeight = ((maxDropHeight > 0) && (dropCalculatedSize.height > maxDropHeight))
? maxDropHeight
: dropCalculatedSize.height;
// ensure the drop container is not less than the control width (would be ugly)
var dropWidth = dropCalculatedSize.width < controlWidth ? controlWidth : dropCalculatedSize.width;
$(dropWrapper).css({
height: dropHeight + "px",
width: dropWidth + "px"
});
dropWrapper.find(".ui-dropdownchecklist-dropcontainer").css({
height: dropHeight + "px"
});
},
// Initializes the plugin
_init: function() {
var self = this, options = this.options;
if ( $.ui.dropdownchecklist.gIDCounter == null) {
$.ui.dropdownchecklist.gIDCounter = 1;
}
// item blurring relies on a cancelable timer
self.blurringItem = null;
// sourceSelect is the select on which the plugin is applied
var sourceSelect = self.element;
self.initialDisplay = sourceSelect.css("display");
sourceSelect.css("display", "none");
self.initialMultiple = sourceSelect.prop("multiple");
self.isMultiple = self.initialMultiple;
if (options.forceMultiple != null) { self.isMultiple = options.forceMultiple; }
sourceSelect.prop("multiple", true);
self.sourceSelect = sourceSelect;
// append the control that resembles a single selection select
var controlWrapper = self._appendControl();
self.controlWrapper = controlWrapper;
self.controlSelector = controlWrapper.find(".ui-dropdownchecklist-selector");
// create the drop container where the items are shown
var dropWrapper = self._appendDropContainer(controlWrapper);
self.dropWrapper = dropWrapper;
// append the items from the source select element
var dropCalculatedSize = self._appendItems();
// updates the text shown in the control
self._updateControlText(controlWrapper, dropWrapper, sourceSelect);
// set the sizes of control and drop container
self._setSize(dropCalculatedSize);
// look for possible auto-check needed on first item
if ( options.firstItemChecksAll ) {
self._syncSelected(null);
}
// BGIFrame for IE6
if (options.bgiframe && typeof self.dropWrapper.bgiframe == "function") {
self.dropWrapper.bgiframe();
}
// listen for change events on the source select element
// ensure we avoid processing internally triggered changes
self.sourceSelect.change(function(event, eventName) {
if (eventName != 'ddcl_internal') {
self._sourceSelectChangeHandler(event);
}
});
},
// Refresh the disable and check state from the underlying control
_refreshOption: function(item,disabled,selected) {
var aParent = item.parent();
// account for enabled/disabled
if ( disabled ) {
item.prop("disabled",true);
item.removeClass("active");
item.addClass("inactive");
aParent.addClass("ui-state-disabled");
} else {
item.prop("disabled",false);
item.removeClass("inactive");
item.addClass("active");
aParent.removeClass("ui-state-disabled");
}
// adjust the checkbox state
item.prop("checked",selected);
},
_refreshGroup: function(group,disabled) {
if ( disabled ) {
group.addClass("ui-state-disabled");
} else {
group.removeClass("ui-state-disabled");
}
},
// External command to explicitly close the dropdown
close: function() {
this._toggleDropContainer(false);
},
// External command to refresh the ddcl from the underlying selector
refresh: function() {
var self = this, sourceSelect = this.sourceSelect, dropWrapper = this.dropWrapper;
var allCheckBoxes = dropWrapper.find("input");
var allGroups = dropWrapper.find(".ui-dropdownchecklist-group");
var groupCount = 0;
var optionCount = 0;
sourceSelect.children().each(function(index) {
var opt = $(this);
var disabled = opt.prop("disabled");
if (opt.is("option")) {
var selected = opt.prop("selected");
var anItem = $(allCheckBoxes[optionCount]);
self._refreshOption(anItem, disabled, selected);
optionCount += 1;
} else if (opt.is("optgroup")) {
var text = opt.attr("label");
if (text != "") {
var aGroup = $(allGroups[groupCount]);
self._refreshGroup(aGroup, disabled);
groupCount += 1;
}
opt.children("option").each(function() {
var subopt = $(this);
var subdisabled = (disabled || subopt.prop("disabled"));
var selected = subopt.prop("selected");
var subItem = $(allCheckBoxes[optionCount]);
self._refreshOption(subItem, subdisabled, selected );
optionCount += 1;
});
}
});
// sync will handle firstItemChecksAll and updateControlText
self._syncSelected(null);
},
// External command to enable the ddcl control
enable: function() {
this.controlSelector.removeClass("ui-state-disabled");
this.disabled = false;
},
// External command to disable the ddcl control
disable: function() {
this.controlSelector.addClass("ui-state-disabled");
this.disabled = true;
},
// External command to destroy all traces of the ddcl control
destroy: function() {
$.Widget.prototype.destroy.apply(this, arguments);
this.sourceSelect.css("display", this.initialDisplay);
this.sourceSelect.prop("multiple", this.initialMultiple);
this.controlWrapper.unbind().remove();
this.dropWrapper.remove();
}
});
$.extend($.ui.dropdownchecklist, {
defaults: {
width: null
, maxDropHeight: null
, firstItemChecksAll: false
, closeRadioOnClick: false
, minWidth: 50
, positionHow: 'absolute'
, bgiframe: false
, explicitClose: null
}
});
})(jQuery);

View File

@ -0,0 +1,49 @@
.ui-dropdownchecklist {
font-size: medium;
color: black;
}
.ui-dropdownchecklist-selector {
height: 20px;
border: 1px solid #ddd;
background: #fff;
}
.ui-state-hover, .ui-state-active {
border-color: #5794bf;
}
.ui-dropdownchecklist-dropcontainer {
background-color: #fff;
border: 1px solid #999;
}
.ui-dropdownchecklist-item {
}
.ui-state-hover {
background-color: #39f;
}
.ui-state-disabled label {
color: #ccc;
}
.ui-dropdownchecklist-group {
font-weight: bold;
font-style: italic;
}
.ui-dropdownchecklist-indent {
padding-left: 7px;
}
/* Font size of 0 on the -selector and an explicit medium on -text required to eliminate
descender problems within the containers and still have a valid size for the text */
.ui-dropdownchecklist-selector-wrapper {
vertical-align: middle;
font-size: 0px;
}
.ui-dropdownchecklist-selector {
padding: 1px 2px 2px 2px;
font-size: 0px;
}
.ui-dropdownchecklist-text {
font-size: medium;
/* line-height: 20px; */
}
.ui-dropdownchecklist-group {
padding: 1px 2px 2px 2px;
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,58 @@
/**
* Farbtastic Color Picker 1.2
* © 2008 Steven Wittens
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
.farbtastic_wrapper{
position:absolute;
left:1200px;
top:300px;
}
.farbtastic {
position: relative;
}
.farbtastic * {
position: absolute;
cursor: crosshair;
}
.farbtastic, .farbtastic .wheel {
width: 195px;
height: 195px;
}
.farbtastic .color, .farbtastic .overlay {
top: 47px;
left: 47px;
width: 101px;
height: 101px;
}
.farbtastic .wheel {
background: url(wheel.png) no-repeat;
width: 195px;
height: 195px;
}
.farbtastic .overlay {
background: url(mask.png) no-repeat;
}
.farbtastic .marker {
width: 17px;
height: 17px;
margin: -8px 0 0 -8px;
overflow: hidden;
background: url(marker.png) no-repeat;
}

View File

@ -0,0 +1,348 @@
/**
* Farbtastic Color Picker 1.2
* © 2008 Steven Wittens
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
jQuery.fn.farbtastic = function (callback) {
$.farbtastic(this, callback);
return this;
};
jQuery.farbtastic = function (container, callback) {
var container = $(container).get(0);
return container.farbtastic || (container.farbtastic = new jQuery._farbtastic(container, callback));
}
jQuery._farbtastic = function (container, callback) {
// Store farbtastic object
var fb = this;
// Insert markup
$(container).html('<div class="farbtastic"><div class="color"></div><div class="wheel"></div><div class="overlay"></div><div class="h-marker marker"></div><div class="sl-marker marker"></div></div>');
var e = $('.farbtastic', container);
fb.wheel = $('.wheel', container).get(0);
// Dimensions
fb.radius = 84;
fb.square = 100;
fb.width = 194;
// Fix background PNGs in IE6
if (navigator.appVersion.match(/MSIE [0-6]\./)) {
$('*', e).each(function () {
if (this.currentStyle.backgroundImage != 'none') {
var image = this.currentStyle.backgroundImage;
image = this.currentStyle.backgroundImage.substring(5, image.length - 2);
$(this).css({
'backgroundImage': 'none',
'filter': "progid:DXImageTransform.Microsoft.AlphaImageLoader(enabled=true, sizingMethod=crop, src='" + image + "')"
});
}
});
}
/**
* Link to the given element(s) or callback.
*/
fb.linkTo = function (callback) {
// Unbind previous nodes
if (typeof fb.callback == 'object') {
$(fb.callback).unbind('keyup', fb.updateValue);
}
// Reset color
fb.color = null;
// Bind callback or elements
if (typeof callback == 'function') {
fb.callback = callback;
}
else if (typeof callback == 'object' || typeof callback == 'string') {
fb.callback = $(callback);
fb.callback.bind('keyup', fb.updateValue);
if (fb.callback.get(0).value) {
fb.setColor(fb.callback.get(0).value);
}
}
return this;
}
fb.updateValue = function (event) {
if (this.value && this.value != fb.color) {
fb.setColor(this.value);
}
}
/**
* Change color with HTML syntax #123456
*/
fb.setColor = function (color) {
var unpack = fb.unpack(color);
if (fb.color != color && unpack) {
fb.color = color;
fb.rgb = unpack;
fb.hsl = fb.RGBToHSL(fb.rgb);
fb.updateDisplay();
}
return this;
}
/**
* Change color with HSL triplet [0..1, 0..1, 0..1]
*/
fb.setHSL = function (hsl) {
fb.hsl = hsl;
fb.rgb = fb.HSLToRGB(hsl);
fb.color = fb.pack(fb.rgb);
fb.updateDisplay();
return this;
}
/////////////////////////////////////////////////////
/**
* Retrieve the coordinates of the given event relative to the center
* of the widget.
*/
fb.widgetCoords = function (event) {
var x, y;
var el = event.target || event.srcElement;
var reference = fb.wheel;
if (typeof event.offsetX != 'undefined') {
// Use offset coordinates and find common offsetParent
var pos = { x: event.offsetX, y: event.offsetY };
// Send the coordinates upwards through the offsetParent chain.
var e = el;
while (e) {
e.mouseX = pos.x;
e.mouseY = pos.y;
pos.x += e.offsetLeft;
pos.y += e.offsetTop;
e = e.offsetParent;
}
// Look for the coordinates starting from the wheel widget.
var e = reference;
var offset = { x: 0, y: 0 }
while (e) {
if (typeof e.mouseX != 'undefined') {
x = e.mouseX - offset.x;
y = e.mouseY - offset.y;
break;
}
offset.x += e.offsetLeft;
offset.y += e.offsetTop;
e = e.offsetParent;
}
// Reset stored coordinates
e = el;
while (e) {
e.mouseX = undefined;
e.mouseY = undefined;
e = e.offsetParent;
}
}
else {
// Use absolute coordinates
var pos = fb.absolutePosition(reference);
x = (event.pageX || 0*(event.clientX + $('html').get(0).scrollLeft)) - pos.x;
y = (event.pageY || 0*(event.clientY + $('html').get(0).scrollTop)) - pos.y;
}
// Subtract distance to middle
return { x: x - fb.width / 2, y: y - fb.width / 2 };
}
/**
* Mousedown handler
*/
fb.mousedown = function (event) {
// Capture mouse
if (!document.dragging) {
$(document).bind('mousemove', fb.mousemove).bind('mouseup', fb.mouseup);
document.dragging = true;
}
// Check which area is being dragged
var pos = fb.widgetCoords(event);
fb.circleDrag = Math.max(Math.abs(pos.x), Math.abs(pos.y)) * 2 > fb.square;
// Process
fb.mousemove(event);
return false;
}
/**
* Mousemove handler
*/
fb.mousemove = function (event) {
// Get coordinates relative to color picker center
var pos = fb.widgetCoords(event);
// Set new HSL parameters
if (fb.circleDrag) {
var hue = Math.atan2(pos.x, -pos.y) / 6.28;
if (hue < 0) hue += 1;
fb.setHSL([hue, fb.hsl[1], fb.hsl[2]]);
}
else {
var sat = Math.max(0, Math.min(1, -(pos.x / fb.square) + .5));
var lum = Math.max(0, Math.min(1, -(pos.y / fb.square) + .5));
fb.setHSL([fb.hsl[0], sat, lum]);
}
UniteAdminRev.onColorPickerMoveEvent();
return false;
}
/**
* Mouseup handler
*/
fb.mouseup = function () {
// Uncapture mouse
$(document).unbind('mousemove', fb.mousemove);
$(document).unbind('mouseup', fb.mouseup);
document.dragging = false;
}
/**
* Update the markers and styles
*/
fb.updateDisplay = function () {
// Markers
var angle = fb.hsl[0] * 6.28;
$('.h-marker', e).css({
left: Math.round(Math.sin(angle) * fb.radius + fb.width / 2) + 'px',
top: Math.round(-Math.cos(angle) * fb.radius + fb.width / 2) + 'px'
});
$('.sl-marker', e).css({
left: Math.round(fb.square * (.5 - fb.hsl[1]) + fb.width / 2) + 'px',
top: Math.round(fb.square * (.5 - fb.hsl[2]) + fb.width / 2) + 'px'
});
// Saturation/Luminance gradient
$('.color', e).css('backgroundColor', fb.pack(fb.HSLToRGB([fb.hsl[0], 1, 0.5])));
// Linked elements or callback
if (typeof fb.callback == 'object') {
// Set background/foreground color
$(fb.callback).css({
backgroundColor: fb.color,
color: fb.hsl[2] > 0.5 ? '#000' : '#fff'
});
// Change linked value
$(fb.callback).each(function() {
if (this.value && this.value != fb.color) {
this.value = fb.color;
}
});
}
else if (typeof fb.callback == 'function') {
fb.callback.call(fb, fb.color);
}
}
/**
* Get absolute position of element
*/
fb.absolutePosition = function (el) {
var r = { x: el.offsetLeft, y: el.offsetTop };
// Resolve relative to offsetParent
if (el.offsetParent) {
var tmp = fb.absolutePosition(el.offsetParent);
r.x += tmp.x;
r.y += tmp.y;
}
return r;
};
/* Various color utility functions */
fb.pack = function (rgb) {
var r = Math.round(rgb[0] * 255);
var g = Math.round(rgb[1] * 255);
var b = Math.round(rgb[2] * 255);
return '#' + (r < 16 ? '0' : '') + r.toString(16) +
(g < 16 ? '0' : '') + g.toString(16) +
(b < 16 ? '0' : '') + b.toString(16);
}
fb.unpack = function (color) {
if (color.length == 7) {
return [parseInt('0x' + color.substring(1, 3)) / 255,
parseInt('0x' + color.substring(3, 5)) / 255,
parseInt('0x' + color.substring(5, 7)) / 255];
}
else if (color.length == 4) {
return [parseInt('0x' + color.substring(1, 2)) / 15,
parseInt('0x' + color.substring(2, 3)) / 15,
parseInt('0x' + color.substring(3, 4)) / 15];
}
}
fb.HSLToRGB = function (hsl) {
var m1, m2, r, g, b;
var h = hsl[0], s = hsl[1], l = hsl[2];
m2 = (l <= 0.5) ? l * (s + 1) : l + s - l*s;
m1 = l * 2 - m2;
return [this.hueToRGB(m1, m2, h+0.33333),
this.hueToRGB(m1, m2, h),
this.hueToRGB(m1, m2, h-0.33333)];
}
fb.hueToRGB = function (m1, m2, h) {
h = (h < 0) ? h + 1 : ((h > 1) ? h - 1 : h);
if (h * 6 < 1) return m1 + (m2 - m1) * h * 6;
if (h * 2 < 1) return m2;
if (h * 3 < 2) return m1 + (m2 - m1) * (0.66666 - h) * 6;
return m1;
}
fb.RGBToHSL = function (rgb) {
var min, max, delta, h, s, l;
var r = rgb[0], g = rgb[1], b = rgb[2];
min = Math.min(r, Math.min(g, b));
max = Math.max(r, Math.max(g, b));
delta = max - min;
l = (min + max) / 2;
s = 0;
if (l > 0 && l < 1) {
s = delta / (l < 0.5 ? (2 * l) : (2 - 2 * l));
}
h = 0;
if (delta > 0) {
if (max == r && max != g) h += (g - b) / delta;
if (max == g && max != b) h += (2 + (b - r) / delta);
if (max == b && max != r) h += (4 + (r - g) / delta);
h /= 6;
}
return [h, s, l];
}
// Install mousedown handler (the others are set on the document on-demand)
$('*', e).mousedown(fb.mousedown);
// Init color
fb.setColor('#000000');
// Set linked elements/callback
if (callback) {
fb.linkTo(callback);
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 652 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.0 KiB

View File

@ -0,0 +1,348 @@
/**
* Farbtastic Color Picker 1.2
* © 2008 Steven Wittens
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
jQuery.fn.farbtastic = function (callback) {
jQuery.farbtastic(this, callback);
return this;
};
jQuery.farbtastic = function (container, callback) {
var container = jQuery(container).get(0);
return container.farbtastic || (container.farbtastic = new jQuery._farbtastic(container, callback));
}
jQuery._farbtastic = function (container, callback) {
// Store farbtastic object
var fb = this;
// Insert markup
jQuery(container).html('<div class="farbtastic"><div class="color"></div><div class="wheel"></div><div class="overlay"></div><div class="h-marker marker"></div><div class="sl-marker marker"></div></div>');
var e = jQuery('.farbtastic', container);
fb.wheel = jQuery('.wheel', container).get(0);
// Dimensions
fb.radius = 84;
fb.square = 100;
fb.width = 194;
// Fix background PNGs in IE6
if (navigator.appVersion.match(/MSIE [0-6]\./)) {
jQuery('*', e).each(function () {
if (this.currentStyle.backgroundImage != 'none') {
var image = this.currentStyle.backgroundImage;
image = this.currentStyle.backgroundImage.substring(5, image.length - 2);
jQuery(this).css({
'backgroundImage': 'none',
'filter': "progid:DXImageTransform.Microsoft.AlphaImageLoader(enabled=true, sizingMethod=crop, src='" + image + "')"
});
}
});
}
/**
* Link to the given element(s) or callback.
*/
fb.linkTo = function (callback) {
// Unbind previous nodes
if (typeof fb.callback == 'object') {
jQuery(fb.callback).unbind('keyup', fb.updateValue);
}
// Reset color
fb.color = null;
// Bind callback or elements
if (typeof callback == 'function') {
fb.callback = callback;
}
else if (typeof callback == 'object' || typeof callback == 'string') {
fb.callback = jQuery(callback);
fb.callback.bind('keyup', fb.updateValue);
if (fb.callback.get(0).value) {
fb.setColor(fb.callback.get(0).value);
}
}
return this;
}
fb.updateValue = function (event) {
if (this.value && this.value != fb.color) {
fb.setColor(this.value);
}
}
/**
* Change color with HTML syntax #123456
*/
fb.setColor = function (color) {
var unpack = fb.unpack(color);
if (fb.color != color && unpack) {
fb.color = color;
fb.rgb = unpack;
fb.hsl = fb.RGBToHSL(fb.rgb);
fb.updateDisplay();
}
return this;
}
/**
* Change color with HSL triplet [0..1, 0..1, 0..1]
*/
fb.setHSL = function (hsl) {
fb.hsl = hsl;
fb.rgb = fb.HSLToRGB(hsl);
fb.color = fb.pack(fb.rgb);
fb.updateDisplay();
return this;
}
/////////////////////////////////////////////////////
/**
* Retrieve the coordinates of the given event relative to the center
* of the widget.
*/
fb.widgetCoords = function (event) {
var x, y;
var el = event.target || event.srcElement;
var reference = fb.wheel;
if (typeof event.offsetX != 'undefined') {
// Use offset coordinates and find common offsetParent
var pos = { x: event.offsetX, y: event.offsetY };
// Send the coordinates upwards through the offsetParent chain.
var e = el;
while (e) {
e.mouseX = pos.x;
e.mouseY = pos.y;
pos.x += e.offsetLeft;
pos.y += e.offsetTop;
e = e.offsetParent;
}
// Look for the coordinates starting from the wheel widget.
var e = reference;
var offset = { x: 0, y: 0 }
while (e) {
if (typeof e.mouseX != 'undefined') {
x = e.mouseX - offset.x;
y = e.mouseY - offset.y;
break;
}
offset.x += e.offsetLeft;
offset.y += e.offsetTop;
e = e.offsetParent;
}
// Reset stored coordinates
e = el;
while (e) {
e.mouseX = undefined;
e.mouseY = undefined;
e = e.offsetParent;
}
}
else {
// Use absolute coordinates
var pos = fb.absolutePosition(reference);
x = (event.pageX || 0*(event.clientX + jQuery('html').get(0).scrollLeft)) - pos.x;
y = (event.pageY || 0*(event.clientY + jQuery('html').get(0).scrollTop)) - pos.y;
}
// Subtract distance to middle
return { x: x - fb.width / 2, y: y - fb.width / 2 };
}
/**
* Mousedown handler
*/
fb.mousedown = function (event) {
// Capture mouse
if (!document.dragging) {
jQuery(document).bind('mousemove', fb.mousemove).bind('mouseup', fb.mouseup);
document.dragging = true;
}
// Check which area is being dragged
var pos = fb.widgetCoords(event);
fb.circleDrag = Math.max(Math.abs(pos.x), Math.abs(pos.y)) * 2 > fb.square;
// Process
fb.mousemove(event);
return false;
}
/**
* Mousemove handler
*/
fb.mousemove = function (event) {
// Get coordinates relative to color picker center
var pos = fb.widgetCoords(event);
// Set new HSL parameters
if (fb.circleDrag) {
var hue = Math.atan2(pos.x, -pos.y) / 6.28;
if (hue < 0) hue += 1;
fb.setHSL([hue, fb.hsl[1], fb.hsl[2]]);
}
else {
var sat = Math.max(0, Math.min(1, -(pos.x / fb.square) + .5));
var lum = Math.max(0, Math.min(1, -(pos.y / fb.square) + .5));
fb.setHSL([fb.hsl[0], sat, lum]);
}
UniteAdminRev.onColorPickerMoveEvent(event);
return false;
}
/**
* Mouseup handler
*/
fb.mouseup = function () {
// Uncapture mouse
jQuery(document).unbind('mousemove', fb.mousemove);
jQuery(document).unbind('mouseup', fb.mouseup);
document.dragging = false;
}
/**
* Update the markers and styles
*/
fb.updateDisplay = function () {
// Markers
var angle = fb.hsl[0] * 6.28;
jQuery('.h-marker', e).css({
left: Math.round(Math.sin(angle) * fb.radius + fb.width / 2) + 'px',
top: Math.round(-Math.cos(angle) * fb.radius + fb.width / 2) + 'px'
});
jQuery('.sl-marker', e).css({
left: Math.round(fb.square * (.5 - fb.hsl[1]) + fb.width / 2) + 'px',
top: Math.round(fb.square * (.5 - fb.hsl[2]) + fb.width / 2) + 'px'
});
// Saturation/Luminance gradient
jQuery('.color', e).css('backgroundColor', fb.pack(fb.HSLToRGB([fb.hsl[0], 1, 0.5])));
// Linked elements or callback
if (typeof fb.callback == 'object') {
// Set background/foreground color
jQuery(fb.callback).css({
backgroundColor: fb.color,
color: fb.hsl[2] > 0.5 ? '#000' : '#fff'
});
// Change linked value
jQuery(fb.callback).each(function() {
if (this.value && this.value != fb.color) {
this.value = fb.color;
}
});
}
else if (typeof fb.callback == 'function') {
fb.callback.call(fb, fb.color);
}
}
/**
* Get absolute position of element
*/
fb.absolutePosition = function (el) {
var r = { x: el.offsetLeft, y: el.offsetTop };
// Resolve relative to offsetParent
if (el.offsetParent) {
var tmp = fb.absolutePosition(el.offsetParent);
r.x += tmp.x;
r.y += tmp.y;
}
return r;
};
/* Various color utility functions */
fb.pack = function (rgb) {
var r = Math.round(rgb[0] * 255);
var g = Math.round(rgb[1] * 255);
var b = Math.round(rgb[2] * 255);
return '#' + (r < 16 ? '0' : '') + r.toString(16) +
(g < 16 ? '0' : '') + g.toString(16) +
(b < 16 ? '0' : '') + b.toString(16);
}
fb.unpack = function (color) {
if (color.length == 7) {
return [parseInt('0x' + color.substring(1, 3)) / 255,
parseInt('0x' + color.substring(3, 5)) / 255,
parseInt('0x' + color.substring(5, 7)) / 255];
}
else if (color.length == 4) {
return [parseInt('0x' + color.substring(1, 2)) / 15,
parseInt('0x' + color.substring(2, 3)) / 15,
parseInt('0x' + color.substring(3, 4)) / 15];
}
}
fb.HSLToRGB = function (hsl) {
var m1, m2, r, g, b;
var h = hsl[0], s = hsl[1], l = hsl[2];
m2 = (l <= 0.5) ? l * (s + 1) : l + s - l*s;
m1 = l * 2 - m2;
return [this.hueToRGB(m1, m2, h+0.33333),
this.hueToRGB(m1, m2, h),
this.hueToRGB(m1, m2, h-0.33333)];
}
fb.hueToRGB = function (m1, m2, h) {
h = (h < 0) ? h + 1 : ((h > 1) ? h - 1 : h);
if (h * 6 < 1) return m1 + (m2 - m1) * h * 6;
if (h * 2 < 1) return m2;
if (h * 3 < 2) return m1 + (m2 - m1) * (0.66666 - h) * 6;
return m1;
}
fb.RGBToHSL = function (rgb) {
var min, max, delta, h, s, l;
var r = rgb[0], g = rgb[1], b = rgb[2];
min = Math.min(r, Math.min(g, b));
max = Math.max(r, Math.max(g, b));
delta = max - min;
l = (min + max) / 2;
s = 0;
if (l > 0 && l < 1) {
s = delta / (l < 0.5 ? (2 * l) : (2 - 2 * l));
}
h = 0;
if (delta > 0) {
if (max == r && max != g) h += (g - b) / delta;
if (max == g && max != b) h += (2 + (b - r) / delta);
if (max == b && max != r) h += (4 + (r - g) / delta);
h /= 6;
}
return [h, s, l];
}
// Install mousedown handler (the others are set on the document on-demand)
jQuery('*', e).mousedown(fb.mousedown);
// Init color
fb.setColor('#000000');
// Set linked elements/callback
if (callback) {
fb.linkTo(callback);
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

View File

@ -0,0 +1,198 @@
// tipsy, facebook style tooltips for jquery
// version 1.0.0a
// (c) 2008-2010 jason frame [jason@onehackoranother.com]
// releated under the MIT license
(function($) {
function fixTitle($ele) {
if ($ele.attr('title') || typeof($ele.attr('original-title')) != 'string') {
$ele.attr('original-title', $ele.attr('title') || '').removeAttr('title');
}
}
function Tipsy(element, options) {
this.$element = $(element);
this.options = options;
this.enabled = true;
fixTitle(this.$element);
}
Tipsy.prototype = {
show: function() {
var title = this.getTitle();
if (title && this.enabled) {
var $tip = this.tip();
$tip.find('.tipsy-inner')[this.options.html ? 'html' : 'text'](title);
$tip[0].className = 'tipsy'; // reset classname in case of dynamic gravity
$tip.remove().css({top: 0, left: 0, visibility: 'hidden', display: 'block'}).appendTo(document.body);
var pos = $.extend({}, this.$element.offset(), {
width: this.$element[0].offsetWidth,
height: this.$element[0].offsetHeight
});
var actualWidth = $tip[0].offsetWidth, actualHeight = $tip[0].offsetHeight;
var gravity = (typeof this.options.gravity == 'function')
? this.options.gravity.call(this.$element[0])
: this.options.gravity;
var tp;
switch (gravity.charAt(0)) {
case 'n':
tp = {top: pos.top + pos.height + this.options.offset, left: pos.left + pos.width / 2 - actualWidth / 2};
break;
case 's':
tp = {top: pos.top - actualHeight - this.options.offset, left: pos.left + pos.width / 2 - actualWidth / 2};
break;
case 'e':
tp = {top: pos.top + pos.height / 2 - actualHeight / 2, left: pos.left - actualWidth - this.options.offset};
break;
case 'w':
tp = {top: pos.top + pos.height / 2 - actualHeight / 2, left: pos.left + pos.width + this.options.offset};
break;
}
if (gravity.length == 2) {
if (gravity.charAt(1) == 'w') {
tp.left = pos.left + pos.width / 2 - 15;
} else {
tp.left = pos.left + pos.width / 2 - actualWidth + 15;
}
}
$tip.css(tp).addClass('tipsy-' + gravity);
if (this.options.fade) {
$tip.stop().css({opacity: 0, display: 'block', visibility: 'visible'}).animate({opacity: this.options.opacity});
} else {
$tip.css({visibility: 'visible', opacity: this.options.opacity});
}
}
},
hide: function() {
if (this.options.fade) {
this.tip().stop().fadeOut(function() { $(this).remove(); });
} else {
this.tip().remove();
}
},
getTitle: function() {
var title, $e = this.$element, o = this.options;
fixTitle($e);
var title, o = this.options;
if (typeof o.title == 'string') {
title = $e.attr(o.title == 'title' ? 'original-title' : o.title);
} else if (typeof o.title == 'function') {
title = o.title.call($e[0]);
}
title = ('' + title).replace(/(^\s*|\s*$)/, "");
return title || o.fallback;
},
tip: function() {
if (!this.$tip) {
this.$tip = $('<div class="tipsy"></div>').html('<div class="tipsy-arrow"></div><div class="tipsy-inner"/></div>');
}
return this.$tip;
},
validate: function() {
if (!this.$element[0].parentNode) {
this.hide();
this.$element = null;
this.options = null;
}
},
enable: function() { this.enabled = true; },
disable: function() { this.enabled = false; },
toggleEnabled: function() { this.enabled = !this.enabled; }
};
$.fn.tipsy = function(options) {
if (options === true) {
return this.data('tipsy');
} else if (typeof options == 'string') {
return this.data('tipsy')[options]();
}
options = $.extend({}, $.fn.tipsy.defaults, options);
function get(ele) {
var tipsy = $.data(ele, 'tipsy');
if (!tipsy) {
tipsy = new Tipsy(ele, $.fn.tipsy.elementOptions(ele, options));
$.data(ele, 'tipsy', tipsy);
}
return tipsy;
}
function enter() {
var tipsy = get(this);
tipsy.hoverState = 'in';
if (options.delayIn == 0) {
tipsy.show();
} else {
setTimeout(function() { if (tipsy.hoverState == 'in') tipsy.show(); }, options.delayIn);
}
};
function leave() {
var tipsy = get(this);
tipsy.hoverState = 'out';
if (options.delayOut == 0) {
tipsy.hide();
} else {
setTimeout(function() { if (tipsy.hoverState == 'out') tipsy.hide(); }, options.delayOut);
}
};
if (!options.live) this.each(function() { get(this); });
if (options.trigger != 'manual') {
var binder = options.live ? 'live' : 'bind',
eventIn = options.trigger == 'hover' ? 'mouseenter' : 'focus',
eventOut = options.trigger == 'hover' ? 'mouseleave' : 'blur';
this[binder](eventIn, enter)[binder](eventOut, leave);
}
return this;
};
$.fn.tipsy.defaults = {
delayIn: 0,
delayOut: 0,
fade: false,
fallback: '',
gravity: 'n',
html: false,
live: false,
offset: 0,
opacity: 0.8,
title: 'title',
trigger: 'hover'
};
// Overwrite this method to provide options on a per-element basis.
// For example, you could store the gravity in a 'tipsy-gravity' attribute:
// return $.extend({}, options, {gravity: $(ele).attr('tipsy-gravity') || 'n' });
// (remember - do not modify 'options' in place!)
$.fn.tipsy.elementOptions = function(ele, options) {
return $.metadata ? $.extend({}, options, $(ele).metadata()) : options;
};
$.fn.tipsy.autoNS = function() {
return $(this).offset().top > ($(document).scrollTop() + $(window).height() / 2) ? 's' : 'n';
};
$.fn.tipsy.autoWE = function() {
return $(this).offset().left > ($(document).scrollLeft() + $(window).width() / 2) ? 'e' : 'w';
};
})(jQuery);

View File

@ -0,0 +1,17 @@
Volume in drive D is new disk
Volume Serial Number is 8F44-2151
Directory of d:\xampp\htdocs\dev\wordpress35\wp-content\plugins\revslider\js
02/21/2013 12:13 PM <DIR> .
02/21/2013 12:13 PM <DIR> ..
02/18/2013 12:53 PM 15,813 admin.js
02/21/2013 12:11 PM <DIR> codemirror
02/13/2013 02:18 PM 49,047 edit_layers.js
02/21/2013 12:11 PM <DIR> farbtastic
05/10/2012 12:18 AM 7,587 jquery.tipsy.js
02/21/2013 12:13 PM 0 jui_old.js
02/14/2013 09:18 AM 15,176 rev_admin.js
11/04/2012 06:53 AM 5,743 settings.js
6 File(s) 93,366 bytes
4 Dir(s) 37,371,822,080 bytes free

View File

@ -0,0 +1,671 @@
var RevSliderAdmin = new function(){
var t = this;
/**
* init "slider" view functionality
*/
var initSaveSliderButton = function(ajaxAction){
jQuery("#button_save_slider").click(function(){
//collect data
var data = {
params: UniteSettingsRev.getSettingsObject("form_slider_params"),
main: UniteSettingsRev.getSettingsObject("form_slider_main")
};
//add slider id to the data
if(ajaxAction == "update_slider"){
data.sliderid = jQuery("#sliderid").val();
//some ajax beautifyer
UniteAdminRev.setAjaxLoaderID("loader_update");
UniteAdminRev.setAjaxHideButtonID("button_save_slider");
UniteAdminRev.setSuccessMessageID("update_slider_success");
}
UniteAdminRev.ajaxRequest(ajaxAction ,data);
});
}
/**
* update shortcode from alias value.
*/
var updateShortcode = function(){
var alias = jQuery("#alias").val();
var shortcode = "[rev_slider "+alias+"]";
if(alias == "")
shortcode = "-- wrong alias -- ";
jQuery("#shortcode").val(shortcode);
}
/**
* change fields of the slider view
*/
var enableSliderViewResponsitiveFields = function(enableRes,textMode){
//enable / disable responsitive fields
if(enableRes){
jQuery("#responsitive_row").removeClass("disabled");
jQuery("#responsitive_row input").prop("disabled","");
}else{
jQuery("#responsitive_row").addClass("disabled");
jQuery("#responsitive_row input").prop("disabled","disabled");
}
var textWidth = jQuery("#cellWidth").data("text"+textMode);
var textHeight = jQuery("#cellHeight").data("text"+textMode);
jQuery("#cellWidth").html(textWidth);
jQuery("#cellHeight").html(textHeight);
}
/**
* init slider view custom controls fields.
*/
var initSliderViewCustomControls = function(){
//fixed
jQuery("#slider_type_1").click(function(){
enableSliderViewResponsitiveFields(false,"normal");
});
//responsitive
jQuery("#slider_type_2").click(function(){
enableSliderViewResponsitiveFields(true,"normal");
});
//full width
jQuery("#slider_type_3").click(function(){
enableSliderViewResponsitiveFields(false,"full");
});
//full screen
jQuery("#slider_type_4").click(function(){
enableSliderViewResponsitiveFields(false,"screen");
});
}
/**
* init "slider->add" view.
*/
this.initAddSliderView = function(){
jQuery("#title").focus();
initSaveSliderButton("create_slider");
initShortcode();
initSliderViewCustomControls();
}
/**
* init "slider->edit" view.
*/
this.initEditSliderView = function(){
initShortcode();
initSliderViewCustomControls();
initSaveSliderButton("update_slider");
//delete slider action
jQuery("#button_delete_slider").click(function(){
if(confirm("Do you really want to delete '"+jQuery("#title").val()+"' ?") == false)
return(true);
var data = {sliderid: jQuery("#sliderid").val()}
UniteAdminRev.ajaxRequest("delete_slider" ,data);
});
//api inputs functionality:
jQuery("#api_wrapper .api-input, #api_area").click(function(){
jQuery(this).select().focus();
});
//api button functions:
jQuery("#link_show_api").click(function(){
jQuery("#api_wrapper").show();
jQuery("#link_show_api").addClass("button-selected");
jQuery("#toolbox_wrapper").hide();
jQuery("#link_show_toolbox").removeClass("button-selected");
});
jQuery("#link_show_toolbox").click(function(){
jQuery("#toolbox_wrapper").show();
jQuery("#link_show_toolbox").addClass("button-selected");
jQuery("#api_wrapper").hide();
jQuery("#link_show_api").removeClass("button-selected");
});
//export slider action
jQuery("#button_export_slider").click(function(){
var sliderID = jQuery("#sliderid").val()
var urlAjaxExport = ajaxurl+"?action="+g_uniteDirPlagin+"_ajax_action&client_action=export_slider";
urlAjaxExport += "&sliderid=" + sliderID;
location.href = urlAjaxExport;
});
//preview slider actions
jQuery("#button_preview_slider").click(function(){
var sliderID = jQuery("#sliderid").val()
openPreviewSliderDialog(sliderID);
});
}
/**
* init shortcode functionality in the slider new and slider edit views.
*/
var initShortcode = function(){
//select shortcode text when click on it.
jQuery("#shortcode").focus(function(){
this.select();
});
jQuery("#shortcode").click(function(){
this.select();
});
//update shortcode
jQuery("#alias").change(function(){
updateShortcode();
});
jQuery("#alias").keyup(function(){
updateShortcode();
});
}
/**
* update slides order
*/
var updateSlidesOrder = function(sliderID){
var arrSlideHtmlIDs = jQuery( "#list_slides" ).sortable("toArray");
//get slide id's from html (li) id's
var arrIDs = [];
jQuery(arrSlideHtmlIDs).each(function(index,value){
var slideID = value.replace("slidelist_item_","");
arrIDs.push(slideID);
});
//save order
var data = {arrIDs:arrIDs,sliderID:sliderID};
jQuery("#saving_indicator").show();
UniteAdminRev.ajaxRequest("update_slides_order" ,data,function(){
jQuery("#saving_indicator").hide();
});
}
/**
* init "sliders list" view
*/
this.initSlidersListView = function(){
//import slide dialog
jQuery("#button_import_slider").click(function(){
jQuery("#dialog_import_slider").dialog({
modal:true,
resizable:false,
width:600,
height:300,
closeOnEscape:true,
buttons:{
"Close":function(){
jQuery(this).dialog("close");
}
},
}); //dialog end
});
jQuery(".button_delete_slider").click(function(){
var sliderID = this.id.replace("button_delete_","");
var sliderTitle = jQuery("#slider_title_"+sliderID).text();
if(confirm("Do you really want to delete '"+sliderTitle+"' ?") == false)
return(false);
UniteAdminRev.ajaxRequest("delete_slider" ,{sliderid:sliderID});
});
//duplicate slider action
jQuery(".button_duplicate_slider").click(function(){
var sliderID = this.id.replace("button_duplicate_","");
UniteAdminRev.ajaxRequest("duplicate_slider" ,{sliderid:sliderID});
});
//preview slider action
jQuery(".button_slider_preview").click(function(){
var sliderID = this.id.replace("button_preview_","");
openPreviewSliderDialog(sliderID);
});
}
/**
* open preview slider dialog
*/
var openPreviewSliderDialog = function(sliderID){
jQuery("#dialog_preview_sliders").dialog({
modal:true,
resizable:false,
minWidth:1100,
minHeight:500,
closeOnEscape:true,
buttons:{
"Close":function(){
jQuery(this).dialog("close");
}
},
open:function(event,ui){
var form1 = jQuery("#form_preview")[0];
jQuery("#preview_sliderid").val(sliderID);
form1.action = g_urlAjaxActions;
form1.submit();
},
close:function(){
var form1 = jQuery("#form_preview")[0];
jQuery("#preview_sliderid").val("empty_output");
form1.action = g_urlAjaxActions;
form1.submit();
}
});
}
/**
* init "slides list" view
*/
this.initSlidesListView = function(sliderID){
//set the slides sortable, init save order
jQuery("#list_slides").sortable({
axis:"y",
handle:'.col-handle',
update:function(){updateSlidesOrder(sliderID)}
});
//new slide
jQuery("#button_new_slide, #button_new_slide_top").click(function(){
var dialogTitle = jQuery("#button_new_slide").data("dialogtitle");
UniteAdminRev.openAddImageDialog(dialogTitle, function(obj){
var data = {sliderid:sliderID,obj:obj};
UniteAdminRev.ajaxRequest("add_slide" ,data);
},true); //allow multiple selection
});
//new transparent slide
jQuery("#button_new_slide_transparent, #button_new_slide_transparent_top").click(function(){
jQuery(this).hide();
jQuery(".new_trans_slide_loader").show();
var data = {sliderid:sliderID};
UniteAdminRev.ajaxRequest("add_slide" ,data);
});
//duplicate slide
jQuery(".button_duplicate_slide").click(function(){
var slideID = this.id.replace("button_duplicate_slide_","");
var data = {slideID:slideID,sliderID:sliderID};
UniteAdminRev.ajaxRequest("duplicate_slide" ,data);
});
//copy / move slides
jQuery(".button_copy_slide").click(function(){
if(jQuery(this).hasClass("button-disabled"))
return(false);
var dialogCopy = jQuery("#dialog_copy_move");
var textClose = dialogCopy.data("textclose");
var textUpdate = dialogCopy.data("textupdate");
var objButton = jQuery(this);
var buttons = {};
buttons[textUpdate] = function(){
var slideID = objButton.attr("id").replace("button_copy_slide_","");
var targetSliderID = jQuery("#selectSliders").val();
var operation = "copy";
if(jQuery("#radio_move").prop("checked") == "checked")
operation = "move";
var data = {slideID:slideID,
sliderID:sliderID,
targetSliderID:targetSliderID,
operation:operation};
var objLoader = objButton.siblings(".loader_copy");
objButton.hide();
objLoader.show();
UniteAdminRev.ajaxRequest("copy_move_slide" ,data);
jQuery(this).dialog("close");
};
jQuery("#dialog_copy_move").dialog({
modal:true,
resizable:false,
width:400,
height:300,
closeOnEscape:true,
buttons:buttons
}); //dialog end
});
// delete single slide
jQuery(".button_delete_slide").click(function(){
var slideID = this.id.replace("button_delete_slide_","");
var data = {slideID:slideID,sliderID:sliderID};
if(confirm("Delete this slide?") == false)
return(false);
var objButton = jQuery(this);
var objLoader = objButton.siblings(".loader_delete");
objButton.hide();
objLoader.show();
UniteAdminRev.ajaxRequest("delete_slide" ,data);
});
//change image
jQuery(".col-image .slide_image").click(function(){
var slideID = this.id.replace("slide_image_","");
UniteAdminRev.openAddImageDialog("Select Slide Image",function(urlImage,imageID){
var data = {slider_id:sliderID,slide_id:slideID,url_image:urlImage,image_id:imageID};
UniteAdminRev.ajaxRequest("change_slide_image" ,data);
});
});
//publish / unpublish item
jQuery("#list_slides .icon_state").click(function(){
var objIcon = jQuery(this);
var objLoader = objIcon.siblings(".state_loader");
var slideID = objIcon.data("slideid");
var data = {slider_id:sliderID,slide_id:slideID};
objIcon.hide();
objLoader.show();
UniteAdminRev.ajaxRequest("toggle_slide_state" ,data,function(response){
objIcon.show();
objLoader.hide();
var currentState = response.state;
if(currentState == "published"){
objIcon.removeClass("state_unpublished").addClass("state_published").prop("title","Unpublish Slide");
}else{
objIcon.removeClass("state_published").addClass("state_unpublished").prop("title","Publish Slide");
}
});
});
//preview slide from the slides list:
jQuery("#list_slides .icon_slide_preview").click(function(){
var slideID = jQuery(this).data("slideid");
openPreviewSlideDialog(slideID,false);
});
}
/**
* init "edit slide" view
*/
this.initEditSlideView = function(slideID,sliderID){
// TOGGLE SOME ACCORDION
jQuery('.tp-accordion').click(function() {
var tpacc=jQuery(this);
if (tpacc.hasClass("tpa-closed")) {
tpacc.parent().parent().parent().find('.tp-closeifotheropen').each(function() {
jQuery(this).slideUp(300);
jQuery(this).parent().find('.tp-accordion').addClass("tpa-closed").addClass("box_closed").find('.postbox-arrow2').html("+");
})
tpacc.parent().find('.toggled-content').slideDown(300);
tpacc.removeClass("tpa-closed").removeClass("box_closed");
tpacc.find('.postbox-arrow2').html("-");
} else {
tpacc.parent().find('.toggled-content').slideUp(300);
tpacc.addClass("tpa-closed").addClass("box_closed");
tpacc.find('.postbox-arrow2').html("+");
}
})
// MAKE MAX WIDTH OF CONTAINERS.
jQuery('.mw960').each(function() {
var newmw = jQuery('#divLayers').width();
if (newmw<960) newmw=960;
jQuery(this).css({maxWidth:newmw+"px"});
})
// SORTING AND DEPTH SELECTOR
jQuery('#button_sort_depth').on('click',function() {
jQuery('.layer_sortbox').addClass("depthselected");
jQuery('.layer_sortbox').removeClass("timeselected");
});
jQuery('#button_sort_time').on('click',function() {
jQuery('.layer_sortbox').removeClass("depthselected");
jQuery('.layer_sortbox').addClass("timeselected");
});
//add slide top link
jQuery("#link_add_slide").click(function(){
var data = {
sliderid:sliderID
};
jQuery("#loader_add_slide").show();
UniteAdminRev.ajaxRequest("add_slide_fromslideview" ,data);
});
//save slide actions
jQuery("#button_save_slide").click(function(){
var layers = UniteLayersRev.getLayers();
if(JSON && JSON.stringify)
layers = JSON.stringify(layers);
var data = {
slideid:slideID,
params:UniteSettingsRev.getSettingsObject("form_slide_params"),
layers:layers
};
data.params.slide_bg_color = jQuery("#slide_bg_color").val();
UniteAdminRev.setAjaxHideButtonID("button_save_slide");
UniteAdminRev.setAjaxLoaderID("loader_update");
UniteAdminRev.setSuccessMessageID("update_slide_success");
UniteAdminRev.ajaxRequest("update_slide" ,data);
});
//change image actions
jQuery("#button_change_image").click(function(){
UniteAdminRev.openAddImageDialog("Select Slide Image",function(urlImage,imageID){
if(imageID == undefined)
imageID = "";
//set visual image
jQuery("#divLayers").css("background-image","url("+urlImage+")");
//update setting input
jQuery("#image_url").val(urlImage);
jQuery("#image_id").val(imageID);
}); //dialog
}); //change image click.
// slide options hide / show
jQuery("#link_hide_options").click(function(){
if(jQuery("#slide_params_holder").is(":visible") == true){
jQuery("#slide_params_holder").hide("slow");
jQuery(this).text("Show Slide Options").addClass("link-selected");
}else{
jQuery("#slide_params_holder").show("slow");
jQuery(this).text("Hide Slide Options").removeClass("link-selected");
}
});
//preview slide actions - open preveiw dialog
jQuery("#button_preview_slide").click(function(){
openPreviewSlideDialog(slideID,true);
});
//init background options
jQuery("#radio_back_image, #radio_back_trans, #radio_back_solid").click(function(){
var currentType = jQuery("#background_type").val();
var bgType = jQuery(this).data("bgtype");
if(currentType == bgType)
return(true);
//disable image button
if(bgType != "image")
jQuery("#button_change_image").addClass("button-disabled");
else
jQuery("#button_change_image").removeClass("button-disabled");
if(bgType != "solid")
jQuery("#slide_bg_color").addClass("disabled").prop("disabled","disabled");
else
jQuery("#slide_bg_color").removeClass("disabled").prop("disabled","");
jQuery("#background_type").val(bgType);
setSlideBGByType(bgType);
});
//on change bg color event
UniteAdminRev.setColorPickerCallback(function(){
var bgType = jQuery("#background_type").val();
if(bgType == "solid"){
var bgColor = jQuery("#slide_bg_color").val();
jQuery("#divLayers").css("background-color",bgColor);
}
});
}//init slide view
/**
* open preview slide dialog
*/
var openPreviewSlideDialog = function(slideID,useParams){
if(useParams === undefined)
useParams = true;
var iframePreview = jQuery("#frame_preview");
var previewWidth = iframePreview.width() + 10;
var previewHeight = iframePreview.height() + 10;
var iframe = jQuery("#frame_preview");
jQuery("#dialog_preview").dialog({
modal:true,
resizable:false,
minWidth:previewWidth,
minHeight:previewHeight,
closeOnEscape:true,
buttons:{
"Close":function(){
jQuery(this).dialog("close");
}
},
open:function(event,ui){
var form1 = jQuery("#form_preview_slide")[0];
var objData = {
slideid:slideID,
};
if(useParams == true){
objData.params = UniteSettingsRev.getSettingsObject("form_slide_params"),
objData.params.slide_bg_color = jQuery("#slide_bg_color").val();
objData.layers = UniteLayersRev.getLayers()
}
var jsonData = JSON.stringify(objData);
jQuery("#preview_slide_data").val(jsonData);
form1.action = g_urlAjaxActions;
form1.client_action = "preview_slide";
form1.submit();
},
close:function(){ //distroy the loaded preview
var form1 = jQuery("#form_preview_slide")[0];
form1.action = g_urlAjaxActions;
jQuery("#preview_slide_data").val("empty_output");
form1.submit();
}
});
}
/**
* set slide background by type (image, solid, bg).
*/
var setSlideBGByType = function(bgType){
switch(bgType){
case "image":
var urlImage = jQuery("#image_url").val();
jQuery("#divLayers").css("background-image","url('"+urlImage+"')");
jQuery("#divLayers").css("background-color","transparent");
jQuery("#divLayers").removeClass("trans_bg");
break;
case "trans":
jQuery("#divLayers").css("background-image","none");
jQuery("#divLayers").css("background-color","transparent");
jQuery("#divLayers").addClass("trans_bg");
break;
case "solid":
jQuery("#divLayers").css("background-image","none");
jQuery("#divLayers").removeClass("trans_bg");
var bgColor = jQuery("#slide_bg_color").val();
jQuery("#divLayers").css("background-color",bgColor);
break;
}
}
}

View File

@ -0,0 +1,263 @@
var UniteSettingsRev = new function(){
var arrControls = {};
var colorPicker;
var t=this;
this.getSettingsObject = function(formID){
var obj = new Object();
var form = document.getElementById(formID);
var name,value,type,flagUpdate;
//enabling all form items connected to mx
var len = form.elements.length;
for(var i=0; i<len; i++){
var element = form.elements[i];
name = element.name;
value = element.value;
type = element.type;
if(jQuery(element).hasClass("wp-editor-area"))
type = "editor";
//trace(name + " " + type);
flagUpdate = true;
switch(type){
case "checkbox":
value = form.elements[i].checked;
break;
case "radio":
if(form.elements[i].checked == false)
flagUpdate = false;
break;
case "editor":
value = tinyMCE.get(name).getContent();
break;
case "select-multiple":
value = jQuery(element).val();
if(value)
value = value.toString();
break;
}
if(flagUpdate == true && name != undefined) obj[name] = value;
}
return(obj);
}
/**
* on selects change - impiment the hide/show, enabled/disables functionality
*/
var onSettingChange = function(){
var controlValue = this.value.toLowerCase();
var controlName = this.name;
if(!arrControls[this.name]) return(false);
jQuery(arrControls[this.name]).each(function(){
var childInput = document.getElementById(this.name);
var childRow = document.getElementById(this.name + "_row");
var value = this.value.toLowerCase();
var isChildRadio = (childInput && childInput.tagName == "SPAN" && jQuery(childInput).hasClass("radio_wrapper"));
switch(this.type){
case "enable":
case "disable":
if(childInput){ //disable
if(this.type == "enable" && controlValue != this.value || this.type == "disable" && controlValue == this.value){
childRow.className = "disabled";
if(childInput){
childInput.disabled = true;
childInput.style.color = "";
}
if(isChildRadio)
jQuery(childInput).children("input").prop("disabled","disabled").addClass("disabled");
}
else{ //enable
childRow.className = "";
if(childInput)
childInput.disabled = false;
if(isChildRadio)
jQuery(childInput).children("input").prop("disabled","").removeClass("disabled");
//color the input again
if(jQuery(childInput).hasClass("inputColorPicker")) g_picker.linkTo(childInput);
}
}
break;
case "show":
if(controlValue == this.value) jQuery(childRow).show();
else jQuery(childRow).hide();
break;
case "hide":
if(controlValue == this.value) jQuery(childRow).hide();
else jQuery(childRow).show();
break;
}
});
}
/**
* combine controls to one object, and init control events.
*/
var initControls = function(){
//combine controls
for(key in g_settingsObj){
var obj = g_settingsObj[key];
for(controlKey in obj.controls){
arrControls[controlKey] = obj.controls[controlKey];
}
}
//init events
jQuery(".settings_wrapper select").change(onSettingChange);
jQuery(".settings_wrapper input[type='radio']").change(onSettingChange);
}
//init color picker
var initColorPicker = function(){
var colorPickerWrapper = jQuery('#divColorPicker');
colorPicker = jQuery.farbtastic('#divColorPicker');
jQuery(".inputColorPicker").focus(function(){
colorPicker.linkTo(this);
colorPickerWrapper.show();
var input = jQuery(this);
var offset = input.offset();
var offsetView = jQuery("#viewWrapper").offset();
colorPickerWrapper.css({
"left":offset.left + input.width()+20-offsetView.left,
"top":offset.top - colorPickerWrapper.height() + 100-offsetView.top
});
}).click(function(){
return(false); //prevent body click
});
colorPickerWrapper.click(function(){
return(false); //prevent body click
});
jQuery("body").click(function(){
colorPickerWrapper.hide();
});
}
/**
* close all accordion items
*/
var closeAllAccordionItems = function(formID){
jQuery("#"+formID+" .unite-postbox .inside").slideUp("fast");
jQuery("#"+formID+" .unite-postbox h3").addClass("box_closed");
}
/**
* init side settings accordion - started from php
*/
t.initAccordion = function(formID){
var classClosed = "box_closed";
jQuery("#"+formID+" .unite-postbox h3").click(function(){
var handle = jQuery(this);
//open
if(handle.hasClass(classClosed)){
closeAllAccordionItems(formID);
handle.removeClass(classClosed).siblings(".inside").slideDown("fast");
}else{ //close
handle.addClass(classClosed).siblings(".inside").slideUp("fast");
}
});
}
/**
* image search
*/
var initImageSearch = function(){
jQuery(".button-image-select").click(function(){
var settingID = this.id.replace("_button","");
UniteAdminRev.openAddImageDialog("Choose Image",function(urlImage){
//update input:
jQuery("#"+settingID).val(urlImage);
//update preview image:
var urlShowImage = UniteAdminRev.getUrlShowImage(urlImage,100,70,true);
jQuery("#" + settingID + "_button_preview").html("<img width='100' height='70' src='"+urlShowImage+"'></img>");
});
})
}
/**
* init the settings function, set the tootips on sidebars.
*/
var init = function(){
//init tipsy
jQuery(".list_settings li .setting_text").tipsy({
gravity:"e",
delayIn: 70
});
jQuery(".tipsy_enabled_top").tipsy({
gravity:"s",
delayIn: 70
});
//init controls
initControls();
initColorPicker();
initImageSearch();
//init checklist
jQuery(".settings_wrapper .input_checklist").each(function(){
var select = jQuery(this);
var minWidth = select.data("minwidth");
var options = {
zIndex:1000
};
if(minWidth)
options.minWidth = minWidth;
select.dropdownchecklist(options);
});
}
//call "constructor"
jQuery(document).ready(function(){
init();
});
} // UniteSettings class end