Presets: support Marked description layout
parent
989816a2e1
commit
35d7cb699c
|
@ -54,6 +54,7 @@
|
||||||
"@panter/vue-i18next": "^0.15.2",
|
"@panter/vue-i18next": "^0.15.2",
|
||||||
"bluebird": "^3.7.2",
|
"bluebird": "^3.7.2",
|
||||||
"djv": "^2.1.4",
|
"djv": "^2.1.4",
|
||||||
|
"dompurify": "^2.3.6",
|
||||||
"i18next": "^19.0.0",
|
"i18next": "^19.0.0",
|
||||||
"i18next-xhr-backend": "^3.2.2",
|
"i18next-xhr-backend": "^3.2.2",
|
||||||
"inflection": "^1.12.0",
|
"inflection": "^1.12.0",
|
||||||
|
|
|
@ -500,7 +500,6 @@ GuiControl.prototype.saveToTextFileDialog = function(textToSave, suggestedFileNa
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
GuiControl.prototype._saveToTextFileDialogFileSelected = function(entry, textToSave, resolve, reject) {
|
GuiControl.prototype._saveToTextFileDialogFileSelected = function(entry, textToSave, resolve, reject) {
|
||||||
checkChromeRuntimeError();
|
checkChromeRuntimeError();
|
||||||
|
|
||||||
|
@ -533,7 +532,6 @@ GuiControl.prototype._saveToTextFileDialogFileSelected = function(entry, textToS
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
GuiControl.prototype.readTextFileDialog = function(extension) {
|
GuiControl.prototype.readTextFileDialog = function(extension) {
|
||||||
const accepts = [{ description: `${extension.toUpperCase()} files`, extensions: [extension] }];
|
const accepts = [{ description: `${extension.toUpperCase()} files`, extensions: [extension] }];
|
||||||
|
|
||||||
|
@ -560,7 +558,6 @@ GuiControl.prototype.readTextFileDialog = function(extension) {
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
GuiControl.prototype.escapeHtml = function(unsafe) {
|
GuiControl.prototype.escapeHtml = function(unsafe) {
|
||||||
return unsafe
|
return unsafe
|
||||||
.replace(/&/g, "&")
|
.replace(/&/g, "&")
|
||||||
|
@ -570,5 +567,11 @@ GuiControl.prototype.escapeHtml = function(unsafe) {
|
||||||
.replace(/'/g, "'");
|
.replace(/'/g, "'");
|
||||||
};
|
};
|
||||||
|
|
||||||
|
GuiControl.prototype.addLinksTargetBlank = function(element) {
|
||||||
|
element.find('a').each(function() {
|
||||||
|
$(this).attr('target', '_blank');
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
// initialize object into GUI variable
|
// initialize object into GUI variable
|
||||||
window.GUI = new GuiControl();
|
window.GUI = new GuiControl();
|
||||||
|
|
|
@ -84,10 +84,9 @@ firmware_flasher.initialize = function (callback) {
|
||||||
|
|
||||||
let formattedNotes = summary.notes.replace(/#(\d+)/g, '[#$1](https://github.com/betaflight/betaflight/pull/$1)');
|
let formattedNotes = summary.notes.replace(/#(\d+)/g, '[#$1](https://github.com/betaflight/betaflight/pull/$1)');
|
||||||
formattedNotes = marked.parse(formattedNotes);
|
formattedNotes = marked.parse(formattedNotes);
|
||||||
|
formattedNotes = DOMPurify.sanitize(formattedNotes);
|
||||||
$('div.release_info .notes').html(formattedNotes);
|
$('div.release_info .notes').html(formattedNotes);
|
||||||
$('div.release_info .notes').find('a').each(function() {
|
GUI.addLinksTargetBlank($('div.release_info .notes'));
|
||||||
$(this).attr('target', '_blank');
|
|
||||||
});
|
|
||||||
|
|
||||||
if (self.releases) {
|
if (self.releases) {
|
||||||
$('div.release_info').slideDown();
|
$('div.release_info').slideDown();
|
||||||
|
|
|
@ -59,6 +59,7 @@
|
||||||
<!-- CORDOVA_INCLUDE js/cordova_startup.js -->
|
<!-- CORDOVA_INCLUDE js/cordova_startup.js -->
|
||||||
<script type="text/javascript" src="./node_modules/lru_map/lru.js"></script>
|
<script type="text/javascript" src="./node_modules/lru_map/lru.js"></script>
|
||||||
<script type="text/javascript" src="./node_modules/marked/marked.min.js"></script>
|
<script type="text/javascript" src="./node_modules/marked/marked.min.js"></script>
|
||||||
|
<script type="text/javascript" src="./node_modules/dompurify/dist/purify.min.js"></script>
|
||||||
<script type="text/javascript" src="./node_modules/universal-ga/lib/analytics.min.js"></script>
|
<script type="text/javascript" src="./node_modules/universal-ga/lib/analytics.min.js"></script>
|
||||||
<script type="text/javascript" src="./node_modules/short-unique-id/dist/short-unique-id.min.js"></script>
|
<script type="text/javascript" src="./node_modules/short-unique-id/dist/short-unique-id.min.js"></script>
|
||||||
<script type="text/javascript" src="./node_modules/object-hash/dist/object_hash.js"></script>
|
<script type="text/javascript" src="./node_modules/object-hash/dist/object_hash.js"></script>
|
||||||
|
|
|
@ -41,6 +41,39 @@
|
||||||
user-select: text;
|
user-select: text;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#presets_detailed_dialog_html_description {
|
||||||
|
white-space: normal;
|
||||||
|
}
|
||||||
|
|
||||||
|
#presets_detailed_dialog_html_description h1, h2 {
|
||||||
|
padding-top: 10px;
|
||||||
|
padding-bottom: 3px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#presets_detailed_dialog_html_description h3 {
|
||||||
|
padding-top: 5px;
|
||||||
|
padding-bottom: 0px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#presets_detailed_dialog_html_description h4, h5, h6 {
|
||||||
|
padding-top: 0px;
|
||||||
|
padding-bottom: 0px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#presets_detailed_dialog_html_description ul, ol {
|
||||||
|
padding-left: 25px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#presets_detailed_dialog_html_description ul li {
|
||||||
|
padding-left: 12px;
|
||||||
|
list-style-type: disclosure-closed;
|
||||||
|
}
|
||||||
|
|
||||||
|
#presets_detailed_dialog_html_description ol li {
|
||||||
|
padding-left: 12px;
|
||||||
|
list-style-type: decimal;
|
||||||
|
}
|
||||||
|
|
||||||
#presets_detailed_dialog_properties {
|
#presets_detailed_dialog_properties {
|
||||||
height: 360px;
|
height: 360px;
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,6 +7,7 @@
|
||||||
<select multiple="multiple" id="presets_options_select"></select>
|
<select multiple="multiple" id="presets_options_select"></select>
|
||||||
</div>
|
</div>
|
||||||
<div class="presets_detailed_dialog_text" id="presets_detailed_dialog_text_description"></div>
|
<div class="presets_detailed_dialog_text" id="presets_detailed_dialog_text_description"></div>
|
||||||
|
<div class="presets_detailed_dialog_text" id="presets_detailed_dialog_html_description"></div>
|
||||||
<div class="presets_detailed_dialog_text" id="presets_detailed_dialog_text_cli"></div>
|
<div class="presets_detailed_dialog_text" id="presets_detailed_dialog_text_cli"></div>
|
||||||
</div>
|
</div>
|
||||||
<div id = "presets_detailed_dialog_loading" class="data-loading"></div>
|
<div id = "presets_detailed_dialog_loading" class="data-loading"></div>
|
||||||
|
|
|
@ -7,6 +7,7 @@ class PresetsDetailedDialog {
|
||||||
this._finalDialogYesNoSettings = {};
|
this._finalDialogYesNoSettings = {};
|
||||||
this._onPresetPickedCallback = onPresetPickedCallback;
|
this._onPresetPickedCallback = onPresetPickedCallback;
|
||||||
this._openPromiseResolve = undefined;
|
this._openPromiseResolve = undefined;
|
||||||
|
this._isDescriptionHtml = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
load() {
|
load() {
|
||||||
|
@ -57,7 +58,7 @@ class PresetsDetailedDialog {
|
||||||
}
|
}
|
||||||
|
|
||||||
_loadPresetUi() {
|
_loadPresetUi() {
|
||||||
this._domDescription.text(this._preset.description?.join("\n"));
|
this._loadDescription();
|
||||||
|
|
||||||
this._domGitHubLink.attr("href", this._presetsRepo.getPresetOnlineLink(this._preset));
|
this._domGitHubLink.attr("href", this._presetsRepo.getPresetOnlineLink(this._preset));
|
||||||
|
|
||||||
|
@ -76,6 +77,24 @@ class PresetsDetailedDialog {
|
||||||
this._showCliText(false);
|
this._showCliText(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_loadDescription() {
|
||||||
|
let text = this._preset.description?.join("\n");
|
||||||
|
|
||||||
|
switch(this._preset.parser) {
|
||||||
|
case "MARKED":
|
||||||
|
this._isDescriptionHtml = true;
|
||||||
|
text = marked.parse(text);
|
||||||
|
text = DOMPurify.sanitize(text);
|
||||||
|
this._domDescriptionHtml.html(text);
|
||||||
|
GUI.addLinksTargetBlank(this._domDescriptionHtml);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
this._isDescriptionHtml = false;
|
||||||
|
this._domDescriptionText.text(text);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
_updateFinalCliText() {
|
_updateFinalCliText() {
|
||||||
this._domCliText.text(this._getFinalCliText().join("\n"));
|
this._domCliText.text(this._getFinalCliText().join("\n"));
|
||||||
}
|
}
|
||||||
|
@ -107,7 +126,8 @@ class PresetsDetailedDialog {
|
||||||
this._domError = $('#presets_detailed_dialog_error');
|
this._domError = $('#presets_detailed_dialog_error');
|
||||||
this._domProperties = $('#presets_detailed_dialog_properties');
|
this._domProperties = $('#presets_detailed_dialog_properties');
|
||||||
this._titlePanel = $('.preset_detailed_dialog_title_panel');
|
this._titlePanel = $('.preset_detailed_dialog_title_panel');
|
||||||
this._domDescription = $('#presets_detailed_dialog_text_description');
|
this._domDescriptionText = $('#presets_detailed_dialog_text_description');
|
||||||
|
this._domDescriptionHtml = $('#presets_detailed_dialog_html_description');
|
||||||
this._domCliText = $('#presets_detailed_dialog_text_cli');
|
this._domCliText = $('#presets_detailed_dialog_text_cli');
|
||||||
this._domGitHubLink = this._domDialog.find('#presets_open_online');
|
this._domGitHubLink = this._domDialog.find('#presets_open_online');
|
||||||
this._domDiscussionLink = this._domDialog.find('#presets_open_discussion');
|
this._domDiscussionLink = this._domDialog.find('#presets_open_discussion');
|
||||||
|
@ -118,7 +138,8 @@ class PresetsDetailedDialog {
|
||||||
}
|
}
|
||||||
|
|
||||||
_showCliText(value) {
|
_showCliText(value) {
|
||||||
this._domDescription.toggle(!value);
|
this._domDescriptionText.toggle(!value && !this._isDescriptionHtml);
|
||||||
|
this._domDescriptionHtml.toggle(!value && this._isDescriptionHtml);
|
||||||
this._domCliText.toggle(value);
|
this._domCliText.toggle(value);
|
||||||
this._domButtonCliShow.toggle(!value);
|
this._domButtonCliShow.toggle(!value);
|
||||||
this._domButtonCliHide.toggle(value);
|
this._domButtonCliHide.toggle(value);
|
||||||
|
|
|
@ -6,7 +6,7 @@ class PresetParser {
|
||||||
}
|
}
|
||||||
|
|
||||||
readPresetProperties(preset, strings) {
|
readPresetProperties(preset, strings) {
|
||||||
const propertiesToRead = ["description", "discussion", "warning", "disclaimer", "include_warning", "include_disclaimer", "discussion", "force_options_review"];
|
const propertiesToRead = ["description", "discussion", "warning", "disclaimer", "include_warning", "include_disclaimer", "discussion", "force_options_review", "parser"];
|
||||||
const propertiesMetadata = {};
|
const propertiesMetadata = {};
|
||||||
preset.options = [];
|
preset.options = [];
|
||||||
|
|
||||||
|
@ -113,11 +113,19 @@ class PresetParser {
|
||||||
case this._settings.MetadataTypes.BOOLEAN:
|
case this._settings.MetadataTypes.BOOLEAN:
|
||||||
this._processBooleanProperty(preset, line, propertyName);
|
this._processBooleanProperty(preset, line, propertyName);
|
||||||
break;
|
break;
|
||||||
|
case this._settings.MetadataTypes.PARSER:
|
||||||
|
this._processParserProperty(preset, line, propertyName);
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
this.console.err(`Parcing preset: unknown property type '${this._settings.presetsFileMetadata[property].type}' for the property '${propertyName}'`);
|
this.console.err(`Parcing preset: unknown property type '${this._settings.presetsFileMetadata[property].type}' for the property '${propertyName}'`);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_processParserProperty(preset, line, propertyName)
|
||||||
|
{
|
||||||
|
preset[propertyName] = line;
|
||||||
|
}
|
||||||
|
|
||||||
_processBooleanProperty(preset, line, propertyName) {
|
_processBooleanProperty(preset, line, propertyName) {
|
||||||
const trueValues = ["true", "yes"];
|
const trueValues = ["true", "yes"];
|
||||||
|
|
||||||
|
|
|
@ -2630,6 +2630,11 @@ domain-browser@^1.2.0:
|
||||||
resolved "https://registry.yarnpkg.com/domain-browser/-/domain-browser-1.2.0.tgz#3d31f50191a6749dd1375a7f522e823d42e54eda"
|
resolved "https://registry.yarnpkg.com/domain-browser/-/domain-browser-1.2.0.tgz#3d31f50191a6749dd1375a7f522e823d42e54eda"
|
||||||
integrity sha512-jnjyiM6eRyZl2H+W8Q/zLMA481hzi0eszAaBUzIVnmYVDBbnLxVNnfu1HgEBvCbL+71FrxMl3E6lpKH7Ge3OXA==
|
integrity sha512-jnjyiM6eRyZl2H+W8Q/zLMA481hzi0eszAaBUzIVnmYVDBbnLxVNnfu1HgEBvCbL+71FrxMl3E6lpKH7Ge3OXA==
|
||||||
|
|
||||||
|
dompurify@^2.3.6:
|
||||||
|
version "2.3.6"
|
||||||
|
resolved "https://registry.yarnpkg.com/dompurify/-/dompurify-2.3.6.tgz#2e019d7d7617aacac07cbbe3d88ae3ad354cf875"
|
||||||
|
integrity sha512-OFP2u/3T1R5CEgWCEONuJ1a5+MFKnOYpkywpUSxv/dj1LeBT1erK+JwM7zK0ROy2BRhqVCf0LRw/kHqKuMkVGg==
|
||||||
|
|
||||||
dot-prop@^4.1.0:
|
dot-prop@^4.1.0:
|
||||||
version "4.2.1"
|
version "4.2.1"
|
||||||
resolved "https://registry.yarnpkg.com/dot-prop/-/dot-prop-4.2.1.tgz#45884194a71fc2cda71cbb4bceb3a4dd2f433ba4"
|
resolved "https://registry.yarnpkg.com/dot-prop/-/dot-prop-4.2.1.tgz#45884194a71fc2cda71cbb4bceb3a4dd2f433ba4"
|
||||||
|
|
Loading…
Reference in New Issue