throttle mozImport after 100ms, display progress after 500ms
* Ctrl-Enter = append button * Shift-Ctrl-Enter = replace button * instantaneous readiness of import dialog on non-blank input * code dedup: addSections() * trimNewLines() -> trim()
This commit is contained in:
		
							parent
							
								
									102b5e03d4
								
							
						
					
					
						commit
						8517e392fe
					
				
							
								
								
									
										170
									
								
								edit/edit.js
									
									
									
									
									
								
							
							
						
						
									
										170
									
								
								edit/edit.js
									
									
									
									
									
								
							|  | @ -1360,45 +1360,56 @@ function isUsercss(style) { | ||||||
| 
 | 
 | ||||||
| function initWithSectionStyle({style, codeIsUpdated}) { | function initWithSectionStyle({style, codeIsUpdated}) { | ||||||
|   setStyleMeta(style); |   setStyleMeta(style); | ||||||
| 
 |   if (codeIsUpdated !== false) { | ||||||
|   if (codeIsUpdated === false) { |  | ||||||
|     setCleanGlobal(); |  | ||||||
|     updateTitle(); |  | ||||||
|     return; |  | ||||||
|   } |  | ||||||
|   // if this was done in response to an update, we need to clear existing sections
 |  | ||||||
|     editors.length = 0; |     editors.length = 0; | ||||||
|     getSections().forEach(div => div.remove()); |     getSections().forEach(div => div.remove()); | ||||||
|   const queue = style.sections.length ? style.sections.slice() : [{code: ''}]; |     addSections(style.sections.length ? style.sections : [{code: ''}]); | ||||||
|   const t0 = performance.now(); |  | ||||||
|   maximizeCodeHeight.stats = null; |  | ||||||
|   // after 100ms the sections will be added asynchronously
 |  | ||||||
|   while (performance.now() - t0 <= 100 && queue.length) { |  | ||||||
|     add(); |  | ||||||
|   } |  | ||||||
|   (function processQueue() { |  | ||||||
|     if (queue.length) { |  | ||||||
|       add(); |  | ||||||
|       setTimeout(processQueue); |  | ||||||
|       if (performance.now() - t0 > 500) { |  | ||||||
|         setGlobalProgress(editors.length, style.sections.length); |  | ||||||
|       } |  | ||||||
|     } else { |  | ||||||
|       setGlobalProgress(); |  | ||||||
|     } |  | ||||||
|   })(); |  | ||||||
|   editors[0].focus(); |  | ||||||
|     initHooks(); |     initHooks(); | ||||||
|  |   } | ||||||
|   setCleanGlobal(); |   setCleanGlobal(); | ||||||
|   updateTitle(); |   updateTitle(); | ||||||
|  | } | ||||||
| 
 | 
 | ||||||
|   function add() { | function addSections(sections, onAdded = () => {}) { | ||||||
|     const sectionDiv = addSection(null, queue.shift()); |   if (addSections.running) { | ||||||
|     maximizeCodeHeight(sectionDiv, !queue.length); |     console.error('addSections cannot be re-entered: please report to the developers'); | ||||||
|     if (!queue.length) { |     // TODO: handle this properly e.g. on update/import
 | ||||||
|  |     return; | ||||||
|  |   } | ||||||
|  |   addSections.running = true; | ||||||
|  |   maximizeCodeHeight.stats = null; | ||||||
|  |   // make a shallow copy since we might run asynchronously
 | ||||||
|  |   // and the original array might get modified
 | ||||||
|  |   sections = sections.slice(); | ||||||
|  |   const t0 = performance.now(); | ||||||
|  |   const divs = []; | ||||||
|  |   let index = 0; | ||||||
|  |   return new Promise(function run(resolve) { | ||||||
|  |     while (index < sections.length) { | ||||||
|  |       const div = addSection(null, sections[index]); | ||||||
|  |       maximizeCodeHeight(div, index === sections.length - 1); | ||||||
|  |       onAdded(div, index); | ||||||
|  |       divs.push(div); | ||||||
|  |       index++; | ||||||
|  |       const elapsed = performance.now() - t0; | ||||||
|  |       if (elapsed > 500) { | ||||||
|  |         setGlobalProgress(index, sections.length); | ||||||
|  |       } | ||||||
|  |       if (elapsed > 100) { | ||||||
|  |         // after 100ms the sections are added asynchronously
 | ||||||
|  |         setTimeout(run, 0, resolve); | ||||||
|  |         return; | ||||||
|  |       } | ||||||
|  |     } | ||||||
|  |     if (divs[0]) { | ||||||
|  |       makeSectionVisible(divs[0].CodeMirror); | ||||||
|  |       divs[0].CodeMirror.focus(); | ||||||
|  |     } | ||||||
|     editors.last.state.renderLintReportNow = true; |     editors.last.state.renderLintReportNow = true; | ||||||
|     } |     addSections.running = false; | ||||||
|   } |     setGlobalProgress(); | ||||||
|  |     resolve(divs); | ||||||
|  |   }); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| function setupOptionsExpand() { | function setupOptionsExpand() { | ||||||
|  | @ -1657,75 +1668,62 @@ function fromMozillaFormat() { | ||||||
|         name: 'import-replace', |         name: 'import-replace', | ||||||
|         textContent: t('importReplaceLabel'), |         textContent: t('importReplaceLabel'), | ||||||
|         title: t('importReplaceTooltip'), |         title: t('importReplaceTooltip'), | ||||||
|         onclick: doImport, |         onclick: () => doImport({replaceOldStyle: true}), | ||||||
|       }), |       }), | ||||||
|     ]})); |     ]})); | ||||||
| 
 |  | ||||||
|   const contents = $('.contents', popup); |   const contents = $('.contents', popup); | ||||||
|   contents.insertBefore(popup.codebox.display.wrapper, contents.firstElementChild); |   contents.insertBefore(popup.codebox.display.wrapper, contents.firstElementChild); | ||||||
|   popup.codebox.focus(); |   popup.codebox.focus(); | ||||||
|   popup.codebox.on('change', () => { |   popup.codebox.on('changes', cm => { | ||||||
|     clearTimeout(popup.mozillaTimeout); |     popup.classList.toggle('ready', !cm.isBlank()); | ||||||
|     popup.mozillaTimeout = setTimeout(() => { |  | ||||||
|       popup.classList.toggle('ready', trimNewLines(popup.codebox.getValue())); |  | ||||||
|     }, 100); |  | ||||||
|   }); |   }); | ||||||
|  |   // overwrite default extraKeys as those are inapplicable in popup context
 | ||||||
|  |   popup.codebox.options.extraKeys = { | ||||||
|  |     'Ctrl-Enter': doImport, | ||||||
|  |     'Shift-Ctrl-Enter': () => doImport({replaceOldStyle: true}), | ||||||
|  |   }; | ||||||
| 
 | 
 | ||||||
|   function doImport(event) { |   function doImport({replaceOldStyle = false}) { | ||||||
|     const replaceOldStyle = event.target.name === 'import-replace'; |     lockPageUI(true); | ||||||
|     const mozStyle = trimNewLines(popup.codebox.getValue()); |     new Promise(setTimeout) | ||||||
| 
 |       .then(() => mozParser.parse(popup.codebox.getValue().trim())) | ||||||
|     mozParser.parse(mozStyle) |       .then(sections => { | ||||||
|       .then(updateSection) |         removeOldSections(replaceOldStyle); | ||||||
|       .then(() => { |         return addSections(sections, div => setCleanItem(div, false)); | ||||||
|         editors.forEach(cm => updateLintReportIfEnabled(cm, 1)); |       }) | ||||||
|         editors.last.state.renderLintReportNow = true; |       .then(sectionDivs => { | ||||||
|  |         sectionDivs.forEach(div => updateLintReportIfEnabled(div.CodeMirror, 1)); | ||||||
|         $('.dismiss', popup).onclick(); |         $('.dismiss', popup).onclick(); | ||||||
|       }) |       }) | ||||||
|       .catch(showError); |       .catch(showError) | ||||||
|  |       .then(() => lockPageUI(false)); | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  |   function removeOldSections(removeAll) { | ||||||
|  |     let toRemove; | ||||||
|  |     if (removeAll) { | ||||||
|  |       toRemove = editors.slice().reverse(); | ||||||
|  |     } else if (editors.last.isBlank() && $('.applies-to-everything', editors.last.getSection())) { | ||||||
|  |       toRemove = [editors.last]; | ||||||
|  |     } else { | ||||||
|  |       return; | ||||||
|  |     } | ||||||
|  |     toRemove.forEach(cm => removeSection({target: cm.getSection()})); | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  |   function lockPageUI(locked) { | ||||||
|  |     document.documentElement.style.pointerEvents = locked ? 'none' : ''; | ||||||
|  |     popup.classList.toggle('ready', locked ? false : !popup.codebox.isBlank()); | ||||||
|  |     popup.codebox.options.readOnly = locked; | ||||||
|  |     popup.codebox.display.wrapper.style.opacity = locked ? '.5' : ''; | ||||||
|  |   } | ||||||
| 
 | 
 | ||||||
|   function showError(errors) { |   function showError(errors) { | ||||||
|       if (!Array.isArray(errors)) { |  | ||||||
|         errors = [errors]; |  | ||||||
|       } |  | ||||||
|     showHelp(t('styleFromMozillaFormatError'), $element({ |     showHelp(t('styleFromMozillaFormatError'), $element({ | ||||||
|       tag: 'pre', |       tag: 'pre', | ||||||
|         textContent: errors.join('\n'), |       textContent: Array.isArray(errors) ? errors.join('\n') : errors, | ||||||
|     })); |     })); | ||||||
|   } |   } | ||||||
| 
 |  | ||||||
|     function updateSection(sections) { |  | ||||||
|       if (replaceOldStyle) { |  | ||||||
|         editors.slice(0).reverse().forEach(cm => { |  | ||||||
|           removeSection({target: cm.getSection().firstElementChild}); |  | ||||||
|         }); |  | ||||||
|       } else if (!editors.last.getValue()) { |  | ||||||
|         // nuke the last blank section
 |  | ||||||
|         if ($('.applies-to-everything', editors.last.getSection())) { |  | ||||||
|           removeSection({target: editors.last.getSection()}); |  | ||||||
|         } |  | ||||||
|       } |  | ||||||
| 
 |  | ||||||
|       const firstSection = sections[0]; |  | ||||||
|       setCleanItem(addSection(null, firstSection), false); |  | ||||||
|       const firstAddedCM = editors.last; |  | ||||||
|       for (const section of sections.slice(1)) { |  | ||||||
|         setCleanItem(addSection(null, section), false); |  | ||||||
|       } |  | ||||||
| 
 |  | ||||||
|       delete maximizeCodeHeight.stats; |  | ||||||
|       editors.forEach(cm => { |  | ||||||
|         maximizeCodeHeight(cm.getSection(), cm === editors.last); |  | ||||||
|       }); |  | ||||||
| 
 |  | ||||||
|       makeSectionVisible(firstAddedCM); |  | ||||||
|       firstAddedCM.focus(); |  | ||||||
|     } |  | ||||||
|   } |  | ||||||
| 
 |  | ||||||
|   function trimNewLines(s) { |  | ||||||
|     return s.replace(/^[\s\n]+/, '').replace(/[\s\n]+$/, ''); |  | ||||||
|   } |  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| function showSectionHelp() { | function showSectionHelp() { | ||||||
|  |  | ||||||
		Loading…
	
		Reference in New Issue
	
	Block a user