"മീഡിയവിക്കി:Gadget-WikiEditMobile.js" എന്ന താളിന്റെ പതിപ്പുകൾ തമ്മിലുള്ള വ്യത്യാസം
A lightweight mobile first editor |
fixing toolbar and buttons |
||
| വരി 94: | വരി 94: | ||
'#wem-overlay[hidden]{display:none}', | '#wem-overlay[hidden]{display:none}', | ||
/* Header bar */ | /* Header bar — compact to save vertical space */ | ||
'#wem-hdr{', | '#wem-hdr{', | ||
'background:#3366cc;color:#fff;', | 'background:#3366cc;color:#fff;', | ||
'padding: | 'padding:5px 8px;display:flex;align-items:center;gap:6px;', | ||
'min-height: | 'min-height:40px;flex-shrink:0;', | ||
'}', | '}', | ||
'#wem-back{', | '#wem-back{', | ||
'background:none;border:none;color:#fff;font-size: | 'background:none;border:none;color:#fff;font-size:20px;', | ||
'cursor:pointer;padding:4px | 'cursor:pointer;padding:4px 6px;line-height:1;', | ||
'touch-action:manipulation;flex-shrink:0;', | |||
'}', | |||
'#wem-close{', | |||
'background:none;border:none;color:#fff;font-size:18px;', | |||
'cursor:pointer;padding:4px 6px;line-height:1;', | |||
'touch-action:manipulation;flex-shrink:0;', | 'touch-action:manipulation;flex-shrink:0;', | ||
'}', | '}', | ||
'#wem-hdr-title{', | '#wem-hdr-title{', | ||
'flex:1;font-size: | 'flex:1;font-size:15px;font-weight:600;', | ||
'white-space:nowrap;overflow:hidden;text-overflow:ellipsis;', | 'white-space:nowrap;overflow:hidden;text-overflow:ellipsis;', | ||
'}', | '}', | ||
'#wem-save{', | '#wem-save{', | ||
'background:#27ae60;border:none;color:#fff;', | 'background:#27ae60;border:none;color:#fff;', | ||
'padding: | 'padding:5px 10px;border-radius:4px;font-size:13px;font-weight:600;', | ||
'cursor:pointer;touch-action:manipulation;flex-shrink:0;', | 'cursor:pointer;touch-action:manipulation;flex-shrink:0;', | ||
'transition:opacity .15s;', | 'transition:opacity .15s;', | ||
| വരി 132: | വരി 137: | ||
'#wem-editor{flex:1;display:flex;flex-direction:column;overflow:hidden;min-height:0}', | '#wem-editor{flex:1;display:flex;flex-direction:column;overflow:hidden;min-height:0}', | ||
/* Toolbar — sits | /* Toolbar — sits just below the header, above content. | ||
soft keyboard | Moving to top avoids being hidden behind the soft keyboard. */ | ||
'#wem-toolbar{', | '#wem-toolbar{', | ||
'display:flex;align-items:center;flex-wrap:nowrap;', | 'display:flex;align-items:center;flex-wrap:nowrap;', | ||
'overflow-x:auto;-webkit-overflow-scrolling:touch;scrollbar-width:none;', | 'overflow-x:auto;-webkit-overflow-scrolling:touch;scrollbar-width:none;', | ||
'background:#f8f9fa;', | 'background:#f8f9fa;', | ||
'border- | 'border-bottom:2px solid #c8ccd1;', | ||
'padding:4px 6px;', | |||
'padding: | 'gap:3px;flex-shrink:0;', | ||
'gap: | |||
'}', | '}', | ||
'#wem-toolbar[hidden]{display:none}', | '#wem-toolbar[hidden]{display:none}', | ||
'#wem-toolbar::-webkit-scrollbar{display:none}', | '#wem-toolbar::-webkit-scrollbar{display:none}', | ||
'.wem-btn{', | '.wem-btn{', | ||
'flex-shrink:0;min-width: | 'flex-shrink:0;min-width:36px;height:36px;padding:0 6px;', | ||
'background:#fff;border:1px solid #c8ccd1;border-radius: | 'background:#fff;border:1px solid #c8ccd1;border-radius:5px;', | ||
'font-size: | 'font-size:15px;cursor:pointer;touch-action:manipulation;', | ||
'display:flex;align-items:center;justify-content:center;', | 'display:flex;align-items:center;justify-content:center;', | ||
'transition:background .1s;white-space:nowrap;', | 'transition:background .1s;white-space:nowrap;', | ||
'}', | '}', | ||
'.wem-btn:active,.wem-btn.wem-active{background:#d0d7f0;border-color:#3366cc}', | '.wem-btn:active,.wem-btn.wem-active{background:#d0d7f0;border-color:#3366cc}', | ||
'.wem-sep{width:1px;height: | '.wem-sep{width:1px;height:26px;background:#c8ccd1;flex-shrink:0;margin:0 1px}', | ||
/* Edit summary row — shown only in editor view */ | |||
'#wem-summary-row{', | |||
'display:flex;align-items:center;gap:6px;', | |||
'padding:5px 8px;background:#f8f9fa;', | |||
'border-top:1px solid #eaecf0;flex-shrink:0;', | |||
'}', | |||
'#wem-summary-row[hidden]{display:none}', | |||
'#wem-summary{', | |||
'flex:1;padding:5px 8px;font-size:13px;', | |||
'border:1px solid #c8ccd1;border-radius:4px;', | |||
'background:#fff;min-width:0;', | |||
'}', | |||
'#wem-summary:focus{outline:none;border-color:#3366cc}', | |||
/* The contentEditable editing surface */ | /* The contentEditable editing surface */ | ||
| വരി 171: | വരി 185: | ||
'#wem-editable ul,#wem-editable ol{padding-left:1.6em;margin:4px 0}', | '#wem-editable ul,#wem-editable ol{padding-left:1.6em;margin:4px 0}', | ||
'#wem-editable p{margin:4px 0}', | '#wem-editable p{margin:4px 0}', | ||
'#wem-editable table{border-collapse:collapse;font-size:13px}', | '#wem-editable table.wikitable{border-collapse:collapse;font-size:13px;width:100%}', | ||
'#wem-editable td,#wem-editable th{border:1px solid #a2a9b1;padding:4px 6px}', | '#wem-editable table.wikitable td,#wem-editable table.wikitable th{border:1px solid #a2a9b1;padding:4px 6px}', | ||
'#wem-editable table.wikitable th{background:#eaecf0;font-weight:bold;text-align:left}', | |||
/* Status bar */ | /* Status bar */ | ||
| വരി 312: | വരി 327: | ||
* @returns {Promise<Object>} API response | * @returns {Promise<Object>} API response | ||
*/ | */ | ||
function saveSection(sectionIndex, wikitext) { | function saveSection(sectionIndex, wikitext, summary) { | ||
var tag = ' ([[User:' + USER + '/WikiEditMobile.js|WikiEditMobile]])'; | |||
return mwApi.postWithToken('csrf', { | return mwApi.postWithToken('csrf', { | ||
action: 'edit', | action: 'edit', | ||
| വരി 318: | വരി 334: | ||
section: sectionIndex, | section: sectionIndex, | ||
text: wikitext, | text: wikitext, | ||
summary: 'Visual mobile edit | summary: (summary ? summary + tag : 'Visual mobile edit' + tag), | ||
format: 'json', | format: 'json', | ||
}); | }); | ||
| വരി 786: | വരി 802: | ||
}, | }, | ||
function onInsert(v) { | function onInsert(v) { | ||
var html = '<table | var html = '<table class="wikitable"><tbody>'; | ||
for (var r = 0; r < v.rows; r++) { | for (var r = 0; r < v.rows; r++) { | ||
html += '<tr>'; | html += '<tr>'; | ||
for (var c = 0; c < v.cols; c++) { | for (var c = 0; c < v.cols; c++) { | ||
if (r === 0 && v.header) { | if (r === 0 && v.header) { | ||
html += '<th | html += '<th>Header ' + (c + 1) + '</th>'; | ||
} else { | } else { | ||
html += '<td | html += '<td> </td>'; | ||
} | } | ||
} | } | ||
| വരി 827: | വരി 843: | ||
curView = 'sections'; | curView = 'sections'; | ||
curSection = null; | curSection = null; | ||
document.getElementById('wem-sections').hidden | document.getElementById('wem-sections').hidden = false; | ||
document.getElementById('wem-editor').hidden | document.getElementById('wem-editor').hidden = true; | ||
document.getElementById('wem-toolbar').hidden = true; | document.getElementById('wem-toolbar').hidden = true; | ||
document.getElementById('wem-summary-row').hidden = true; | |||
document.getElementById('wem-hdr-title').textContent = 'Edit article'; | document.getElementById('wem-hdr-title').textContent = 'Edit article'; | ||
document.getElementById('wem-save'). | document.getElementById('wem-save').hidden = true; | ||
document.getElementById('wem-back').style.visibility = 'hidden'; | document.getElementById('wem-back').style.visibility = 'hidden'; | ||
setStatus(''); | setStatus(''); | ||
| വരി 841: | വരി 858: | ||
curSection = section; | curSection = section; | ||
document.getElementById('wem-sections').hidden = true; | document.getElementById('wem-sections').hidden = true; | ||
document.getElementById('wem-editor').hidden | document.getElementById('wem-editor').hidden = false; | ||
document.getElementById('wem-toolbar').hidden | document.getElementById('wem-toolbar').hidden = false; | ||
document.getElementById('wem-summary-row').hidden = false; | |||
document.getElementById('wem-summary').value = ''; | |||
document.getElementById('wem-hdr-title').textContent = section.line || 'Introduction'; | document.getElementById('wem-hdr-title').textContent = section.line || 'Introduction'; | ||
document.getElementById('wem-back').style.visibility = 'visible'; | document.getElementById('wem-back').style.visibility = 'visible'; | ||
document.getElementById('wem-save').disabled | document.getElementById('wem-save').hidden = false; | ||
document.getElementById('wem-save').disabled = true; | |||
setStatus('Fetching section wikitext…'); | setStatus('Fetching section wikitext…'); | ||
| വരി 872: | വരി 892: | ||
setStatus('Converting back to wikitext…'); | setStatus('Converting back to wikitext…'); | ||
var html = editor.getContent(); | var html = editor.getContent(); | ||
var summary = document.getElementById('wem-summary').value.trim(); | |||
htmlToWikitext(html) | htmlToWikitext(html) | ||
.then(function (wt) { | .then(function (wt) { | ||
setStatus('Saving…'); | setStatus('Saving…'); | ||
return saveSection(curSection.index, wt); | return saveSection(curSection.index, wt, summary); | ||
}) | }) | ||
.then(function (res) { | .then(function (res) { | ||
| വരി 900: | വരി 921: | ||
// ── Header ── | // ── Header ── | ||
var hdr = ce('div', { id: 'wem-hdr' }); | var hdr = ce('div', { id: 'wem-hdr' }); | ||
var back = ce('button', { id: 'wem-back', 'aria-label': 'Back' }); | |||
var back = ce('button', { id: 'wem-back', 'aria-label': 'Back to sections' }); | |||
back.textContent = '←'; | back.textContent = '←'; | ||
| വരി 909: | വരി 931: | ||
saveBtn.textContent = 'Save'; | saveBtn.textContent = 'Save'; | ||
saveBtn.disabled = true; | saveBtn.disabled = true; | ||
saveBtn.hidden = true; | |||
var closeBtn = ce('button', { id: 'wem-close', 'aria-label': 'Close editor' }); | |||
closeBtn.textContent = '✕'; | |||
hdr.appendChild(back); | hdr.appendChild(back); | ||
hdr.appendChild(titleEl); | hdr.appendChild(titleEl); | ||
hdr.appendChild(saveBtn); | hdr.appendChild(saveBtn); | ||
hdr.appendChild(closeBtn); | |||
// ── Toolbar — below header, above content; avoids keyboard overlap ── | |||
var toolbar = ce('div', { id: 'wem-toolbar' }); | |||
toolbar.hidden = true; | |||
// ── Section list view ── | // ── Section list view ── | ||
var sectionsDiv = ce('div', { id: 'wem-sections' }); | var sectionsDiv = ce('div', { id: 'wem-sections' }); | ||
// ── Editor | // ── Editor pane ── | ||
var editorPane = ce('div', { id: 'wem-editor' }); | var editorPane = ce('div', { id: 'wem-editor' }); | ||
editorPane.hidden = true; | editorPane.hidden = true; | ||
| വരി 929: | വരി 960: | ||
editorPane.appendChild(editWrap); | editorPane.appendChild(editWrap); | ||
// ── Status bar | // ── Edit summary row ── | ||
var summaryRow = ce('div', { id: 'wem-summary-row' }); | |||
summaryRow.hidden = true; | |||
var summaryInput = ce('input', { id: 'wem-summary', type: 'text' }); | |||
summaryInput.placeholder = 'Edit summary (optional)…'; | |||
summaryRow.appendChild(summaryInput); | |||
// ── Status bar ── | |||
var status = ce('div', { id: 'wem-status' }); | var status = ce('div', { id: 'wem-status' }); | ||
// ── Dialog backdrop ── | |||
// ── Dialog backdrop | |||
var backdrop = ce('div', { id: 'wem-dialog-backdrop' }); | var backdrop = ce('div', { id: 'wem-dialog-backdrop' }); | ||
backdrop.hidden = true; | backdrop.hidden = true; | ||
// ── Overlay — stacking order | // ── Overlay — stacking order: | ||
// header · sections/editor · status · | // header · toolbar · sections/editor · summary · status · backdrop ── | ||
var overlay = ce('div', { id: 'wem-overlay' }); | var overlay = ce('div', { id: 'wem-overlay' }); | ||
overlay.hidden = true; | overlay.hidden = true; | ||
overlay.appendChild(hdr); | overlay.appendChild(hdr); | ||
overlay.appendChild(toolbar); // ← top, never behind keyboard | |||
overlay.appendChild(sectionsDiv); | overlay.appendChild(sectionsDiv); | ||
overlay.appendChild(editorPane); | overlay.appendChild(editorPane); | ||
overlay.appendChild(summaryRow); | |||
overlay.appendChild(status); | overlay.appendChild(status); | ||
overlay.appendChild(backdrop); | overlay.appendChild(backdrop); | ||
document.body.appendChild(overlay); | document.body.appendChild(overlay); | ||
| വരി 960: | വരി 993: | ||
// ── Events ── | // ── Events ── | ||
back.addEventListener('click', function () { | back.addEventListener('click', function () { | ||
if (!backdrop.hidden) { closeDialog(); return; } | if (!backdrop.hidden) { closeDialog(); return; } | ||
showSectionsView(); | |||
}); | |||
closeBtn.addEventListener('click', function () { | |||
if (!backdrop.hidden) { closeDialog(); } | |||
overlay.hidden = true; | |||
}); | }); | ||