Loading editor/html/js/properties.js +0 −43 Original line number Diff line number Diff line Loading @@ -625,7 +625,6 @@ var PropertiesPanel = (function() { { sep: true }, { cmd: 'insertUnorderedList', icon: '\u2022', title: 'Aufzählung' }, { cmd: 'insertOrderedList', icon: '1.', title: 'Nummerierung' }, { custom: 'listImage', icon: '\u2022\uD83D\uDDBC', title: 'Bild als Aufzählungszeichen' }, { sep: true }, { cmd: 'justifyLeft', icon: '\u2261', title: 'Links' }, { cmd: 'justifyCenter', icon: '\u2263', title: 'Zentriert' }, Loading Loading @@ -759,48 +758,6 @@ var PropertiesPanel = (function() { } }); })(btn, editorDiv, hiddenInput); } else if (def.custom === 'listImage') { (function(b, ed, hi) { b.addEventListener('click', function(e) { e.preventDefault(); if (typeof MediaBrowser === 'undefined') return; MediaBrowser.open(function(mediaItem) { if (!mediaItem || !mediaItem.url) return; ed.focus(); function findList(startNode) { var node = startNode; while (node && node !== ed) { if (node.nodeType === 1 && (node.tagName === 'UL' || node.tagName === 'OL')) { return node; } node = node.parentNode; } return null; } var sel = window.getSelection(); var ul = sel && sel.anchorNode ? findList(sel.anchorNode) : null; if (!ul) { document.execCommand('insertUnorderedList', false, null); sel = window.getSelection(); ul = sel && sel.anchorNode ? findList(sel.anchorNode) : null; } if (ul) { ul.style.listStyle = 'none'; ul.style.paddingLeft = '1.2em'; for (var li = ul.firstElementChild; li; li = li.nextElementSibling) { if (li.tagName !== 'LI') continue; li.style.listStyleType = 'none'; li.style.backgroundImage = "url('" + mediaItem.url + "')"; li.style.backgroundRepeat = 'no-repeat'; li.style.backgroundPosition = '0 0.15em'; li.style.backgroundSize = '14px 14px'; li.style.paddingLeft = '20px'; } hi.value = ed.innerHTML; } }); }); })(btn, editorDiv, hiddenInput); } else if (def.custom === 'source') { (function(b, ed, sa, hi) { b.addEventListener('click', function(e) { Loading editor/widgets/textbox/textbox.cpp +29 −2 Original line number Diff line number Diff line Loading @@ -140,8 +140,9 @@ extern "C" { std::string charCountPosition = "after"; // List bullet style std::string listBullet = "default"; // default,disc,circle,square,none,checkmark,check_green,arrow,arrow_small,star,dash,diamond,cross std::string listBullet = "default"; // default,disc,circle,square,none,checkmark,check_green,arrow,arrow_small,star,dash,diamond,cross,image std::string listBulletColor = ""; std::string listBulletImage = ""; public: Loading Loading @@ -424,8 +425,10 @@ extern "C" { addField("list_bullet", "Aufzählungssymbol", "select", nullptr, "all", mkOpts({"default","disc","circle","square","none", "checkmark","check_green","arrow","arrow_small", "star","dash","diamond","cross"}), "simple"); "star","dash","diamond","cross","image"}), "simple"); addField("list_bullet_color", "Aufzählungsfarbe", "color_var", nullptr, "all", nullptr, "simple"); addField("list_bullet_image", "Aufzählungsbild", "media_browse_url", nullptr, "all", nullptr, "simple", mkVisible("list_bullet", "image")); { const auto &labelMap = (_lang == "de") ? textbox_i18n::de() : textbox_i18n::en(); int n = json_object_array_length(arr); Loading Loading @@ -498,6 +501,7 @@ extern "C" { // List bullet element->SetAttribute("list_bullet", listBullet.c_str()); element->SetAttribute("list_bullet_color", listBulletColor.c_str()); element->SetAttribute("list_bullet_image", listBulletImage.c_str()); if (!customCss.empty()) { tinyxml2::XMLElement* cssEl = doc->NewElement("CustomCss"); Loading Loading @@ -626,6 +630,8 @@ extern "C" { if (val) listBullet = val; val = xml_data->Attribute("list_bullet_color"); if (val) listBulletColor = val; val = xml_data->Attribute("list_bullet_image"); if (val) listBulletImage = val; tinyxml2::XMLElement* cssEl = xml_data->FirstChildElement("CustomCss"); if (cssEl) { Loading Loading @@ -702,6 +708,7 @@ extern "C" { json_object_object_add(obj, "char_count_position", json_object_new_string(charCountPosition.c_str())); json_object_object_add(obj, "list_bullet", json_object_new_string(listBullet.c_str())); json_object_object_add(obj, "list_bullet_color", json_object_new_string(listBulletColor.c_str())); json_object_object_add(obj, "list_bullet_image", json_object_new_string(listBulletImage.c_str())); const char *result = json_object_to_json_string_ext(obj, JSON_C_TO_STRING_NOSLASHESCAPE); std::string out(result); json_object_put(obj); Loading Loading @@ -863,6 +870,10 @@ extern "C" { val = json_object_get_string(val_obj); if (val) listBulletColor = val; } if (json_object_object_get_ex(obj, "list_bullet_image", &val_obj)) { val = json_object_get_string(val_obj); if (val) listBulletImage = val; } json_object_put(obj); } Loading Loading @@ -1024,6 +1035,22 @@ extern "C" { "list-style-type:none;padding-left:0;}" + sel + " ul>li::before," + sel + " ol>li::before{" "content:none;}"; } else if (listBullet == "image") { // Custom image bullet via ::before — fixed box size keeps the // marker readable regardless of the source image's own dimensions. if (!listBulletImage.empty()) { bulletCss = sel + " ul," + sel + " ol{" "list-style-type:none;padding-left:1.4em;}" + sel + " ul>li," + sel + " ol>li{" "position:relative;}" + sel + " ul>li::before," + sel + " ol>li::before{" "content:'';position:absolute;left:-1.2em;top:0.15em;" "width:0.9em;height:0.9em;" "background-image:url('" + listBulletImage + "');" "background-size:contain;background-repeat:no-repeat;" "background-position:center;}"; } } else { // Custom symbol via ::before — literal UTF-8 chars avoid CSS-escape issues static const std::map<std::string,std::string> symbolMap = { Loading Loading
editor/html/js/properties.js +0 −43 Original line number Diff line number Diff line Loading @@ -625,7 +625,6 @@ var PropertiesPanel = (function() { { sep: true }, { cmd: 'insertUnorderedList', icon: '\u2022', title: 'Aufzählung' }, { cmd: 'insertOrderedList', icon: '1.', title: 'Nummerierung' }, { custom: 'listImage', icon: '\u2022\uD83D\uDDBC', title: 'Bild als Aufzählungszeichen' }, { sep: true }, { cmd: 'justifyLeft', icon: '\u2261', title: 'Links' }, { cmd: 'justifyCenter', icon: '\u2263', title: 'Zentriert' }, Loading Loading @@ -759,48 +758,6 @@ var PropertiesPanel = (function() { } }); })(btn, editorDiv, hiddenInput); } else if (def.custom === 'listImage') { (function(b, ed, hi) { b.addEventListener('click', function(e) { e.preventDefault(); if (typeof MediaBrowser === 'undefined') return; MediaBrowser.open(function(mediaItem) { if (!mediaItem || !mediaItem.url) return; ed.focus(); function findList(startNode) { var node = startNode; while (node && node !== ed) { if (node.nodeType === 1 && (node.tagName === 'UL' || node.tagName === 'OL')) { return node; } node = node.parentNode; } return null; } var sel = window.getSelection(); var ul = sel && sel.anchorNode ? findList(sel.anchorNode) : null; if (!ul) { document.execCommand('insertUnorderedList', false, null); sel = window.getSelection(); ul = sel && sel.anchorNode ? findList(sel.anchorNode) : null; } if (ul) { ul.style.listStyle = 'none'; ul.style.paddingLeft = '1.2em'; for (var li = ul.firstElementChild; li; li = li.nextElementSibling) { if (li.tagName !== 'LI') continue; li.style.listStyleType = 'none'; li.style.backgroundImage = "url('" + mediaItem.url + "')"; li.style.backgroundRepeat = 'no-repeat'; li.style.backgroundPosition = '0 0.15em'; li.style.backgroundSize = '14px 14px'; li.style.paddingLeft = '20px'; } hi.value = ed.innerHTML; } }); }); })(btn, editorDiv, hiddenInput); } else if (def.custom === 'source') { (function(b, ed, sa, hi) { b.addEventListener('click', function(e) { Loading
editor/widgets/textbox/textbox.cpp +29 −2 Original line number Diff line number Diff line Loading @@ -140,8 +140,9 @@ extern "C" { std::string charCountPosition = "after"; // List bullet style std::string listBullet = "default"; // default,disc,circle,square,none,checkmark,check_green,arrow,arrow_small,star,dash,diamond,cross std::string listBullet = "default"; // default,disc,circle,square,none,checkmark,check_green,arrow,arrow_small,star,dash,diamond,cross,image std::string listBulletColor = ""; std::string listBulletImage = ""; public: Loading Loading @@ -424,8 +425,10 @@ extern "C" { addField("list_bullet", "Aufzählungssymbol", "select", nullptr, "all", mkOpts({"default","disc","circle","square","none", "checkmark","check_green","arrow","arrow_small", "star","dash","diamond","cross"}), "simple"); "star","dash","diamond","cross","image"}), "simple"); addField("list_bullet_color", "Aufzählungsfarbe", "color_var", nullptr, "all", nullptr, "simple"); addField("list_bullet_image", "Aufzählungsbild", "media_browse_url", nullptr, "all", nullptr, "simple", mkVisible("list_bullet", "image")); { const auto &labelMap = (_lang == "de") ? textbox_i18n::de() : textbox_i18n::en(); int n = json_object_array_length(arr); Loading Loading @@ -498,6 +501,7 @@ extern "C" { // List bullet element->SetAttribute("list_bullet", listBullet.c_str()); element->SetAttribute("list_bullet_color", listBulletColor.c_str()); element->SetAttribute("list_bullet_image", listBulletImage.c_str()); if (!customCss.empty()) { tinyxml2::XMLElement* cssEl = doc->NewElement("CustomCss"); Loading Loading @@ -626,6 +630,8 @@ extern "C" { if (val) listBullet = val; val = xml_data->Attribute("list_bullet_color"); if (val) listBulletColor = val; val = xml_data->Attribute("list_bullet_image"); if (val) listBulletImage = val; tinyxml2::XMLElement* cssEl = xml_data->FirstChildElement("CustomCss"); if (cssEl) { Loading Loading @@ -702,6 +708,7 @@ extern "C" { json_object_object_add(obj, "char_count_position", json_object_new_string(charCountPosition.c_str())); json_object_object_add(obj, "list_bullet", json_object_new_string(listBullet.c_str())); json_object_object_add(obj, "list_bullet_color", json_object_new_string(listBulletColor.c_str())); json_object_object_add(obj, "list_bullet_image", json_object_new_string(listBulletImage.c_str())); const char *result = json_object_to_json_string_ext(obj, JSON_C_TO_STRING_NOSLASHESCAPE); std::string out(result); json_object_put(obj); Loading Loading @@ -863,6 +870,10 @@ extern "C" { val = json_object_get_string(val_obj); if (val) listBulletColor = val; } if (json_object_object_get_ex(obj, "list_bullet_image", &val_obj)) { val = json_object_get_string(val_obj); if (val) listBulletImage = val; } json_object_put(obj); } Loading Loading @@ -1024,6 +1035,22 @@ extern "C" { "list-style-type:none;padding-left:0;}" + sel + " ul>li::before," + sel + " ol>li::before{" "content:none;}"; } else if (listBullet == "image") { // Custom image bullet via ::before — fixed box size keeps the // marker readable regardless of the source image's own dimensions. if (!listBulletImage.empty()) { bulletCss = sel + " ul," + sel + " ol{" "list-style-type:none;padding-left:1.4em;}" + sel + " ul>li," + sel + " ol>li{" "position:relative;}" + sel + " ul>li::before," + sel + " ol>li::before{" "content:'';position:absolute;left:-1.2em;top:0.15em;" "width:0.9em;height:0.9em;" "background-image:url('" + listBulletImage + "');" "background-size:contain;background-repeat:no-repeat;" "background-position:center;}"; } } else { // Custom symbol via ::before — literal UTF-8 chars avoid CSS-escape issues static const std::map<std::string,std::string> symbolMap = { Loading