/** * Inline vzdálená editace * * Knihovna pro umožnění inline editace na vzdáleném serveru * * @category Knihovny funkcí * @copyright Copyright (c) 2016 Foxtrot Technologies s.r.o. (www.foxtrot.cz) * @version 1.1, 2016-05-07 * * Použití uživatelské * =================== * * Stiskem shift+ctrl+alt+e se zapne/vypne editační mód * Klikem na podsvícený objekt je zobrazeno menu s akcemi * * Použití programátorské * ====================== * * Instalace * --------- * 1) Celý adresář OEeditor musí být podadresářem rootu webu * 2) V HEAD nalinkovat všechny JS v adresáři OEeditor * 3) V HEAD nalinkovat CSS všechny v adresáři OEeditor * 4) Na stránce umožnit showWait = * a) v images mít obrázek wait_icon.gif * b) na stránce div s ID "wait_icon_cont" a třídou "hidden" * * Programování * ------------ * 1) V menu výběru objektu zobrazen atribut objektu NAME; pokud není pak ID * 2) Atribut noOE (nemusí být hodnota) vynechá ze zpracování (stejné jako když není uvedeno ID) * 3) Atribut noedit (nemusí být hodnota) zamezí volbu Upravit/Změnit * 4) Atribut nodelete (nemusí být hodnota) zamezí volbu Smazat * 5) Vložení šablony * a) V adresáři OEedit/templates musí existovat textový soubor templates.def. Soubor je ve formátu JSON. * b) Má-li se pro některý objekt na stránce nabíze volba vložení šablony, musí být v tomto souboru nadefinovány, které šablony se daného objektu týkají (jsou pro něj dostupné) - viz příklad níže * c) Musí být v adresář OEedit/templates soubor s definicí šablony (text, který je přenesen do cílového objektu na stránce). Pokud se v textu vyskytuje řetězec %TEMPLATE_SEQUENCE_ID%, je nahrazen sekvenčním číslem unikátním pro výskyt vkládané šablony * * Příklad definičního souboru šablony: * ------------------------------------ * * { * "ID_objektu_do_kterého_bude_vkládáno_viz_5.b_výše": { * "id_prefix": "text_kterým_začíná_ID_kontejneru_vkládané_šablony => musí_být_v_šabloně_nadefinován", * "templates": { * "libovolné_ID_šablony": { * "fle": "název_soubor_kde_je_šablona_nadefinována_viz_5.c_výše", * "name": "název_šablony_který_bude_v_menu_zobrazován_uživateli" * } * * a_dále_to_stejné_odděleno_čárkou_pro_všechny_další_dostupné_šablony_které_uživatel_může_do_tohoto_objektu_vkládat * } * } * * a_dále_to_stejné_odděleno_čárkou_pro_všechny_další_objekty_na_stránce_kam_je_možné_vkládat_šablony * } * * Příklad šablony: * ------------------------------------ * *
*
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed ac nisl nec purus blandit elementum eu ac massa. Mauris nec purus feugiat, mollis lorem a, suscipit turpis. Cras justo turpis, bibendum eget urna sed, ornare varius sapien. Sed consectetur sodales scelerisque. Integer ornare ornare risus, eu venenatis mauris sollicitudin nec. Aenean et justo viverra ex rhoncus mattis at id arcu. Etiam non felis non enim sollicitudin fermentum vitae eget velit. Duis maximus id justo at fermentum.
*
* */ var OE_is_editing = false; var OE_hl_elems = []; var OE_editor_instance; var OE_editor_html = ""; var OE_edited_obj = ""; var OE_done_actions = []; var OE_last_action = {}; var OE_templates = {}; OE_templates.hlavni_main_container = {id_prefix: "article_container_", templates: []}; OE_templates.hlavni_main_container.templates.push({templ_name: "article_foto", name:"Článek (foto, nadpis, text)"}); OE_templates.hlavni_main_container.templates.push({templ_name: "article", name:"Článek (nadpis, text)"}); OE_templates.hlavni_main_container.templates.push({templ_name: "empty", name:"Textový kontejner"}); OE_templates.story_main_container = {id_prefix: "article_container_", templates: []}; OE_templates.story_main_container.templates.push({templ_name: "article_foto", name:"Článek (foto, nadpis, text)"}); OE_templates.story_main_container.templates.push({templ_name: "article", name:"Článek (nadpis, text)"}); OE_templates.story_main_container.templates.push({templ_name: "empty", name:"Textový kontejner"}); OE_templates.game_main_container = {id_prefix: "article_container_", templates: []}; OE_templates.game_main_container.templates.push({templ_name: "article_foto", name:"Článek (foto, nadpis, text)"}); OE_templates.game_main_container.templates.push({templ_name: "article", name:"Článek (nadpis, text)"}); OE_templates.game_main_container.templates.push({templ_name: "empty", name:"Textový kontejner"}); OE_templates.aero_main_container = {id_prefix: "article_container_", templates: []}; OE_templates.aero_main_container.templates.push({templ_name: "article_foto", name:"Článek (foto, nadpis, text)"}); OE_templates.aero_main_container.templates.push({templ_name: "article", name:"Článek (nadpis, text)"}); OE_templates.aero_main_container.templates.push({templ_name: "empty", name:"Textový kontejner"}); $(document).ready(function() { $( document ).keydown(function(e) { if(e.shiftKey && e.ctrlKey && e.altKey && e.which == 69) { if($("#OE_exit_butt").length == 1) { OE_finish_edit(); } else { OE_is_editing = true; OE_hl_elems = []; $("
", { id: 'OE_exit_butt', text: 'konec editace' }).appendTo("body").html("konec
editace").click(OE_finish_edit); if(OE_done_actions.length > 0) OE_create_back_button(); $("
", { id: 'OE_menu_placeholder' }).appendTo("body"); $("", { id: 'OE_pic_uploader', class: "hidden", type: "file", name: "f[]", accept: "image/*" }).appendTo("body"); $.contextMenu({ selector: '#OE_menu_placeholder', trigger: 'none', build: OE_create_menu, autoHide: true }); } } }); OE_set_hover_action(); $( "body" ).click(function(e) { if(OE_is_editing && OE_hl_elems.length > 0) { var position = { x: e.pageX - 10, y: e.pageY - 10 } setTimeout(function(){ $("#OE_menu_placeholder").contextMenu(position); }, 1); } }); }); function OE_set_hover_action() { $( "div,img,label,input,p,span" ).hover( function() { if(OE_is_editing && isVarNonempty($( this ).attr('id')) && $( this ).attr('id').indexOf("OE_")<0 && !varExists($( this ).attr('noOE'))) { if(OE_hl_elems.indexOf($( this ).attr('id')) < 0) { OE_hl_elems.push($( this ).attr('id')); $( this ).addClass( "OE_highlight" ); $("
", { id: 'OE_object_name_plate'+$( this ).attr('id'), class: 'OE_object_name_plate', text: OE_get_object_name($( this ).attr('id')) }).appendTo("body"); var obj_pos = $( this ).position(); var left_margin = parseInt($( this ).css("margin-left").replace("px", "")); var top_margin = parseInt($( this ).css("margin-top").replace("px", "")); $( "#OE_object_name_plate"+$( this ).attr('id')).css({left: Math.round(obj_pos.left+left_margin)+"px", top: Math.round(obj_pos.top-22+top_margin)+"px"}); } } }, function() { if(OE_is_editing && isVarNonempty($( this ).attr('id')) && $( this ).attr('id').indexOf("OE_")<0 && !varExists($( this ).attr('noOE'))) { var elem_pos = OE_hl_elems.indexOf($( this ).attr('id')); if(elem_pos >= 0) { OE_hl_elems.splice(elem_pos,1); $( this ).removeClass( "OE_highlight" ); $( "#OE_object_name_plate"+$( this ).attr('id')).remove(); } } } ); } function OE_finish_edit() { $("#OE_exit_butt").remove(); $("#OE_back_butt").remove(); $("#OE_pic_uploader").remove(); $("#OE_menu_placeholder").remove(); $( "div" ).removeClass( "OE_highlight" ); OE_is_editing = false; } function OE_get_object_name(obj_id) { return isVarNonempty($("#" + obj_id).attr("name"))?$("#" + obj_id).attr("name"):obj_id; } function OE_create_menu ($trigger, e) { var items = {}; for(var i=0; OE_hl_elems.length > i; i++) { var menu_sels = {}; if(!varExists($("#" + OE_hl_elems[i]).attr("noedit"))) { if($("#" + OE_hl_elems[i]).prop("tagName") != "IMG") menu_sels["edit."+OE_hl_elems[i]] = {name: "Upravit", icon: "edit"}; else menu_sels["change."+OE_hl_elems[i]] = {name: "Změnit obrázek", icon: "edit"}; if(isVarNonempty($("#" + OE_hl_elems[i]).css("background-image")) && $("#" + OE_hl_elems[i]).css("background-image")!="none") menu_sels["changeBck."+OE_hl_elems[i]] = {name: "Změnit ikonu", icon: "edit"}; } if(!varExists($("#" + OE_hl_elems[i]).attr("nodelete"))) menu_sels["delete."+OE_hl_elems[i]] = {name: "Smazat", icon: "delete"}; if(isVarNonempty(OE_templates[OE_hl_elems[i]])) { menu_sels["insert.before"] = {name: "Vložit na začátek", icon: "add", items: {}}; for(var j=0; j0) { items[OE_hl_elems[i]] = { name: OE_get_object_name(OE_hl_elems[i]), items: menu_sels }; } } if(getObjectLength(items)==0) return false; else { return { callback: function(key, options) { var command = key.substr(0,key.indexOf(".")); var obj_id = key.substr(key.indexOf(".")+1); switch(command) { case "edit": OE_edit_object(obj_id); break; case "delete": OE_delete_object(obj_id); break; case "insert": var tmp = obj_id.split("."); OE_insert_template(tmp[0],tmp[1],tmp[2]); break; case "change": OE_get_change_pic(obj_id); break; case "changeBck": OE_get_change_bck_pic(obj_id); break; } $("#OE_menu_placeholder").contextMenu("hide"); return false; }, items: items }; } } function OE_remove_editor() { if ( OE_editor_instance ) { OE_editor_html = OE_editor_instance.getData(); OE_editor_instance.destroy(); OE_editor_instance = null; } if($("#OE_editor_modal_cont").length > 0) $("#OE_editor_modal_cont").remove(); } function OE_edit_object(id) { OE_edited_obj = id; if($("#OE_editor_modal_cont").length > 0) OE_remove_editor(); $("
", { id: 'OE_editor_modal_cont' }).appendTo("body"); $("
", { id: 'OE_editor_cont' }).appendTo("#OE_editor_modal_cont"); $("
", { id: 'OE_save_button', text: 'uložit' }).appendTo("#OE_editor_modal_cont").click(function() {OE_save_text();}); $("
", { id: 'OE_cancel_button', text: 'zrušit' }).appendTo("#OE_editor_modal_cont").click(function() {OE_remove_editor();}); var pos = $('#OE_editor_cont').position(); var bwidth = $('#OE_save_button').outerWidth(); var bheight = $('#OE_save_button').height(); $('#OE_save_button').css("top",(pos.top - bheight - 2)+"px"); $('#OE_save_button').css("left",pos.left+"px"); $('#OE_cancel_button').css("top",(pos.top - bheight - 2)+"px"); $('#OE_cancel_button').css("left",(pos.left + bwidth + 2)+"px"); var config = { width: $("#OE_editor_cont").width(), height: $("#OE_editor_cont").height()-80, contentsLanguage: 'cs', entities: false, enterMode: CKEDITOR.ENTER_BR, allowedContent: true }; OE_editor_html = $("#" + id).html(); //console.log(OE_editor_html); OE_editor_instance = CKEDITOR.appendTo( 'OE_editor_cont', config, OE_editor_html ); } function OE_save_text() { OE_remove_editor(); if(isVarNonempty(OE_edited_obj)) { showWait(true); var param = { id: OE_edited_obj, txt: OE_editor_html, cmd: 'edit', fle: location.pathname.substring(location.pathname.lastIndexOf("/")).trim() } OE_last_action = jQuery.extend(true,{}, param); OE_last_action.txt = $("#"+OE_edited_obj).html(); OE_last_action.txt_id = "#"+OE_edited_obj; loadXMLDoc("OEeditor/OEModifyFile.php",param); } } function OE_delete_object(id) { OE_edited_obj = id; OE_editor_html = ""; if(isVarNonempty(OE_edited_obj)) { showWait(true); var param = { id: OE_edited_obj, txt: "", cmd: 'delete', fle: location.pathname.substring(location.pathname.lastIndexOf("/")).trim() } OE_last_action = jQuery.extend(true,{}, param); var parent = $("#"+OE_edited_obj).parent(); while(isVarNonempty(parent) && !isVarNonempty(parent.attr("id")) && parent.prop("tagName") !== "BODY") parent = parent.parent(); if(isVarNonempty(parent)) { OE_last_action.txt = parent.html(); OE_last_action.txt_id = isVarNonempty(parent.attr("id"))?"#"+parent.attr("id"):"body"; } loadXMLDoc("OEeditor/OEModifyFile.php",param); } } function OE_get_change_pic(id) { OE_edited_obj = id; $("#OE_pic_uploader").change(function() { showWait(true); var file = this.files[0]; var param = { id: OE_edited_obj, txt: "", cmd: 'change', fle: location.pathname.substring(location.pathname.lastIndexOf("/")).trim() } OE_last_action = jQuery.extend(true,{}, param); OE_last_action.txt = $("#"+OE_edited_obj).attr("src"); OE_last_action.txt_id = "#"+OE_edited_obj; uploadFile(file,"OEeditor/OEModifyFile.php",param); }); $("#OE_pic_uploader").click(); } function OE_get_change_bck_pic(id) { OE_edited_obj = id; $("#OE_pic_uploader").change(function() { showWait(true); var file = this.files[0]; var param = { id: OE_edited_obj, txt: $("#" + OE_edited_obj).css("background-image"), cmd: 'changeBck', fle: location.pathname.substring(location.pathname.lastIndexOf("/")).trim() } OE_last_action = jQuery.extend(true,{}, param); OE_last_action.txt = $("#" + OE_edited_obj).css("background-image"); OE_last_action.txt_id = "#"+OE_edited_obj; uploadFile(file,"OEeditor/OEModifyFile.php",param); }); $("#OE_pic_uploader").click(); } function OE_image_change_OK(action_id,name) { if($("#OE_back_butt").length == 0) OE_create_back_button(); OE_last_action.action_id = action_id; OE_done_actions.push(jQuery.extend(true,{}, OE_last_action)); $("#"+OE_edited_obj).attr("src","images/" + name + "?" + new Date().getTime()) } function OE_image_bck_change_OK(action_id, name) { if($("#OE_back_butt").length == 0) OE_create_back_button(); OE_last_action.action_id = action_id; OE_last_action.txt = name; OE_done_actions.push(jQuery.extend(true,{}, OE_last_action)); $("#" + OE_edited_obj).css("background-image","url('images/"+name+"?"+new Date().getTime()+"')"); // $("#"+OE_edited_obj).attr("src","images/" + name + "?" + new Date().getTime()) } function OE_insert_template(place,id,tpl) { OE_edited_obj = id; OE_editor_html = ""; if(isVarNonempty(OE_edited_obj)) { showWait(true); var sid = 1, tmp; $( "#" + OE_edited_obj ).children().each(function( index ) { var child_id = $( this ).attr("id"); if(isVarNonempty(child_id) && child_id.indexOf("_")>=0) { tmp = child_id.substr(child_id.lastIndexOf("_")+1); if(!isNaN(tmp)) { tmp = parseInt(tmp); if(tmp >= sid) sid = tmp+1; } } }); var param = { id: OE_edited_obj, place: place, templ: tpl, cmd: 'insert', txt: "", seq_id: sid, fle: location.pathname.substring(location.pathname.lastIndexOf("/")).trim() } OE_last_action = jQuery.extend(true,{}, param); OE_last_action.txt = $("#" + id).html(); OE_last_action.txt_id = "#"+id; loadXMLDoc("OEeditor/OEModifyFile.php",param); } } function OE_change_fail() { } function OE_insert_fail() { } function OE_image_change_fail() { } function OE_image_bck_change_fail() { } function OE_change_OK(action_id) { if($("#OE_back_butt").length == 0) OE_create_back_button(); OE_last_action.action_id = action_id; OE_done_actions.push(jQuery.extend(true,{}, OE_last_action)); $("#"+OE_edited_obj).html(OE_editor_html); OE_set_hover_action(); } function OE_delete_OK(action_id) { if($("#OE_back_butt").length == 0) OE_create_back_button(); OE_last_action.action_id = action_id; OE_done_actions.push(jQuery.extend(true,{}, OE_last_action)); $("#"+OE_edited_obj).remove(); } function OE_insert_OK(action_id, place, txt) { if($("#OE_back_butt").length == 0) OE_create_back_button(); OE_last_action.action_id = action_id; OE_done_actions.push(jQuery.extend(true,{}, OE_last_action)); var html = $("#"+OE_edited_obj).html(); if(place == "before") html = txt.decodePost() + html; else html += txt.decodePost(); $("#"+OE_edited_obj).html(html); OE_set_hover_action(); } function OE_create_back_button() { $("
", { id: 'OE_back_butt' }).appendTo("body").html("o krok
zpět").click(OE_back); } function OE_back() { if(OE_done_actions.length > 0) { showWait(true); var param = { id: OE_done_actions[OE_done_actions.length-1].action_id, cmd: OE_done_actions[OE_done_actions.length-1].cmd } loadXMLDoc("OEeditor/OERestoreFile.php",param); } } function OE_back_fail() { } function OE_back_OK() { var last_action = OE_done_actions.splice(OE_done_actions.length-1,1); if(last_action[0].cmd == "change") $(last_action[0].txt_id).attr("src",last_action[0].txt+"?"+new Date().getTime()); else if(last_action[0].cmd == "changeBck") $(last_action[0].txt_id).css("background-image","url('images/"+last_action[0].txt+"?"+new Date().getTime()+"')"); else $(last_action[0].txt_id).html(last_action[0].txt); if(OE_done_actions.length == 0) $("#OE_back_butt").remove(); OE_set_hover_action(); }