87 lines
		
	
	
		
			2.9 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
			
		
		
	
	
			87 lines
		
	
	
		
			2.9 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
| class Task {
 | |
|     _data = {};
 | |
|     _data_keys = [];
 | |
|     /**
 | |
|      * Create a task.
 | |
|      * constructor(itemsSelector:string, fieldSelectors:string[])
 | |
|      * constructor(itemsSelector:string, fieldSelectors:string[], url:string, from:number, to:number, interval:number)
 | |
|      * constructor(itemsSelector:string, fieldSelectors:string[], url:string, pages:number[])
 | |
|      * constructor(itemsSelector:string, fieldSelectors:string[], urls:string[])
 | |
|      * @param {...any} args
 | |
|      */
 | |
|     constructor(options, ...args) {
 | |
|         if (!testArgs(...args))
 | |
|             throw new Error(`Invalid call arguments.\n\n${signitures}\n\n`);
 | |
|         this._options = options;
 | |
|         this._itemsSelector = args.shift();
 | |
|         this._fieldSelectors = args.shift();
 | |
|         this._urls = parseUrls(...args);
 | |
|     }
 | |
|     load(state) {
 | |
|         this._itemsSelector = state._itemsSelector;
 | |
|         this._data = state._data;
 | |
|         this._data_keys = state._data_keys;
 | |
|         this._itemsSelector = state._itemsSelector;
 | |
|         this._fieldSelectors = state._fieldSelectors;
 | |
|         this._urls = state._urls;
 | |
|         return this;
 | |
|     }
 | |
|     get urls() {
 | |
|         return this._urls;
 | |
|     }
 | |
|     get data() {
 | |
|         return this._data;
 | |
|     }
 | |
|     get results() {
 | |
|         return this._data_keys.reduce((p, c) => {
 | |
|             return p.concat(this._data[c]);
 | |
|         }, []);
 | |
|     }
 | |
|     get fieldSelectors() {
 | |
|         return this._fieldSelectors;
 | |
|     }
 | |
|     clean() {
 | |
|         this._data = {};
 | |
|     }
 | |
|     async execute(tab, upstreamData) {
 | |
|         if (!tab) return Promise.reject("No tab to execute the task.");
 | |
|         let urls = this._urls
 | |
|         if (!urls.length) {
 | |
|             if (upstreamData) {
 | |
|                 urls = parseUrls(upstreamData);
 | |
|             } else {
 | |
|                 urls = [await queryUrl(tab)];
 | |
|             }
 | |
|         }
 | |
|         let saveResult = (results, key) => {
 | |
|             this._data[key] = results;
 | |
|             this._data_keys.push(key);
 | |
|         }
 | |
|         return urls.reduce((p, url, i) => p.then(
 | |
|             results => {
 | |
|                 if (i > 0) {
 | |
|                     if (!MSG_URL_SKIPPED.isEqual(results)) {
 | |
|                         let lastURL = urls[i - 1];
 | |
|                         saveResult(results, lastURL);
 | |
|                     }
 | |
|                 }
 | |
|                 if (this._data[url]) return MSG_URL_SKIPPED;
 | |
|                 let pms = redirectTab(tab, url);
 | |
|                 if (this._options["scrollToBottom"]) {
 | |
|                     pms = pms.then(() => scrollToBottom(tab));
 | |
|                 }
 | |
|                 return pms.then(
 | |
|                     () => extractTabData(tab, this._itemsSelector, this._fieldSelectors)
 | |
|                 );
 | |
|             }
 | |
|         ), Promise.resolve(null)).then(
 | |
|             results => {
 | |
|                 if (!MSG_URL_SKIPPED.isEqual(results)) {
 | |
|                     let lastURL = urls[urls.length - 1];
 | |
|                     saveResult(results, lastURL);
 | |
|                     return;
 | |
|                 }
 | |
|             }
 | |
|         );
 | |
|     }
 | |
| } |