parent
							
								
									79dff2775b
								
							
						
					
					
						commit
						1725c0ecb9
					
				| 
						 | 
				
			
			@ -199,6 +199,18 @@ const styleMan = (() => {
 | 
			
		|||
 | 
			
		||||
    getOrder: () => orderWrap.value,
 | 
			
		||||
 | 
			
		||||
    /** @returns {Promise<string | {[remoteId:string]: styleId}>}>} */
 | 
			
		||||
    async getRemoteInfo(id) {
 | 
			
		||||
      if (ready.then) await ready;
 | 
			
		||||
      if (id) return calcRemoteId(id2style(id));
 | 
			
		||||
      const res = {};
 | 
			
		||||
      for (const {style} of dataMap.values()) {
 | 
			
		||||
        const [rid, vars] = calcRemoteId(style);
 | 
			
		||||
        if (rid) res[rid] = [style.id, vars];
 | 
			
		||||
      }
 | 
			
		||||
      return res;
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    /** @returns {Promise<StyleSectionsToApply>} */
 | 
			
		||||
    async getSectionsByUrl(url, id, isInitialApply) {
 | 
			
		||||
      if (ready.then) await ready;
 | 
			
		||||
| 
						 | 
				
			
			@ -366,6 +378,17 @@ const styleMan = (() => {
 | 
			
		|||
    return id2style(uuidIndex.get(uuid));
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  function calcRemoteId({md5Url, updateUrl, usercssData: ucd} = {}) {
 | 
			
		||||
    let id;
 | 
			
		||||
    id = (id = /\d+/.test(md5Url) || URLS.extractUsoArchiveId(updateUrl)) && `uso-${id}`
 | 
			
		||||
      || (id = URLS.extractUSwId(updateUrl)) && `usw-${id}`
 | 
			
		||||
      || '';
 | 
			
		||||
    return id && [
 | 
			
		||||
      id,
 | 
			
		||||
      ucd && !isEmptyObj(ucd.vars),
 | 
			
		||||
    ];
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /** @returns {StyleObj} */
 | 
			
		||||
  function createNewStyle() {
 | 
			
		||||
    return /** @namespace StyleObj */ {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -134,6 +134,10 @@
 | 
			
		|||
  width: 100%;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.search-result[data-installed] {
 | 
			
		||||
  box-shadow: 1px 1px 10px darkcyan;
 | 
			
		||||
  border-color: darkcyan;
 | 
			
		||||
}
 | 
			
		||||
.search-result:not([data-installed]) .search-result-actions {
 | 
			
		||||
  opacity: 0;
 | 
			
		||||
  transition: opacity .5s;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -2,7 +2,7 @@
 | 
			
		|||
/* global $entry tabURL */// popup.js
 | 
			
		||||
/* global API */// msg.js
 | 
			
		||||
/* global Events */
 | 
			
		||||
/* global FIREFOX URLS debounce download stringAsRegExp tryRegExp tryURL */// toolbox.js
 | 
			
		||||
/* global FIREFOX URLS debounce download isEmptyObj stringAsRegExp tryRegExp tryURL */// toolbox.js
 | 
			
		||||
/* global prefs */
 | 
			
		||||
/* global t */// localization.js
 | 
			
		||||
'use strict';
 | 
			
		||||
| 
						 | 
				
			
			@ -27,7 +27,7 @@
 | 
			
		|||
  /**
 | 
			
		||||
   * @typedef IndexEntry
 | 
			
		||||
   * @prop {'uso' | 'uso-android'} f - format
 | 
			
		||||
   * @prop {Number} i - id
 | 
			
		||||
   * @prop {Number} i - id, later replaced with string like `uso-123`
 | 
			
		||||
   * @prop {string} n - name
 | 
			
		||||
   * @prop {string} c - category
 | 
			
		||||
   * @prop {Number} u - updatedTime
 | 
			
		||||
| 
						 | 
				
			
			@ -39,8 +39,8 @@
 | 
			
		|||
   * @prop {string} sn -  screenshotName
 | 
			
		||||
   * @prop {boolean} sa -  screenshotArchived
 | 
			
		||||
   *
 | 
			
		||||
   * @prop {boolean} _installed
 | 
			
		||||
   * @prop {number} _installedStyleId
 | 
			
		||||
   * @prop {number} _styleId - installed style id
 | 
			
		||||
   * @prop {boolean} _styleVars - installed style has vars
 | 
			
		||||
   * @prop {number} _year
 | 
			
		||||
   */
 | 
			
		||||
  /** @type IndexEntry[] */
 | 
			
		||||
| 
						 | 
				
			
			@ -73,6 +73,7 @@
 | 
			
		|||
    const entry = el.closest(RESULT_SEL);
 | 
			
		||||
    return {entry, result: entry && entry._result};
 | 
			
		||||
  };
 | 
			
		||||
  const rid2id = rid => rid.split('-')[1];
 | 
			
		||||
  Events.searchInline = () => {
 | 
			
		||||
    calcCategory();
 | 
			
		||||
    ready = start();
 | 
			
		||||
| 
						 | 
				
			
			@ -158,18 +159,22 @@
 | 
			
		|||
 | 
			
		||||
  window.on('styleDeleted', ({detail: {style: {id}}}) => {
 | 
			
		||||
    restoreScrollPosition();
 | 
			
		||||
    const result = results.find(r => r._installedStyleId === id);
 | 
			
		||||
    if (result) {
 | 
			
		||||
      API.uso.pingback(result.i, false);
 | 
			
		||||
      renderActionButtons(result.i, -1);
 | 
			
		||||
    const r = results.find(r => r._styleId === id);
 | 
			
		||||
    if (r) {
 | 
			
		||||
      if (r.f) API.uso.pingback(rid2id(r.i), false);
 | 
			
		||||
      delete r._styleId;
 | 
			
		||||
      renderActionButtons(r.i);
 | 
			
		||||
    }
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  window.on('styleAdded', async ({detail: {style}}) => {
 | 
			
		||||
    restoreScrollPosition();
 | 
			
		||||
    const id = calcId(style) || calcId(await API.styles.get(style.id));
 | 
			
		||||
    if (id && results.find(r => r.i === id)) {
 | 
			
		||||
      renderActionButtons(id, style.id);
 | 
			
		||||
    const ri = await API.styles.getRemoteInfo(style.id);
 | 
			
		||||
    const r = ri && results.find(r => ri[0] === r.i);
 | 
			
		||||
    if (r) {
 | 
			
		||||
      r._styleId = style.id;
 | 
			
		||||
      r._styleVars = ri[1];
 | 
			
		||||
      renderActionButtons(ri[0]);
 | 
			
		||||
    }
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -209,9 +214,10 @@
 | 
			
		|||
        results = await search({retry});
 | 
			
		||||
      }
 | 
			
		||||
      if (results.length) {
 | 
			
		||||
        const installedStyles = await API.styles.getAll();
 | 
			
		||||
        const allSupportedIds = new Set(installedStyles.map(calcId));
 | 
			
		||||
        results = results.filter(r => !allSupportedIds.has(r.i));
 | 
			
		||||
        const info = await API.styles.getRemoteInfo();
 | 
			
		||||
        for (const r of results) {
 | 
			
		||||
          [r._styleId, r._styleVars] = info[r.i] || [];
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
      if (!keepYears) resultsAllYears = results;
 | 
			
		||||
      renderYears();
 | 
			
		||||
| 
						 | 
				
			
			@ -330,7 +336,7 @@
 | 
			
		|||
  function createSearchResultNode(result) {
 | 
			
		||||
    const entry = t.template.searchResult.cloneNode(true);
 | 
			
		||||
    const {
 | 
			
		||||
      i: id,
 | 
			
		||||
      i: rid,
 | 
			
		||||
      n: name,
 | 
			
		||||
      r: rating,
 | 
			
		||||
      u: updateTime,
 | 
			
		||||
| 
						 | 
				
			
			@ -342,7 +348,8 @@
 | 
			
		|||
      sn: shot,
 | 
			
		||||
      f: fmt,
 | 
			
		||||
    } = entry._result = result;
 | 
			
		||||
    entry.id = RESULT_ID_PREFIX + id;
 | 
			
		||||
    const id = rid2id(rid);
 | 
			
		||||
    entry.id = RESULT_ID_PREFIX + rid;
 | 
			
		||||
    // title
 | 
			
		||||
    Object.assign($('.search-result-title', entry), {
 | 
			
		||||
      onclick: Events.openURLandHide,
 | 
			
		||||
| 
						 | 
				
			
			@ -421,22 +428,19 @@
 | 
			
		|||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  function renderActionButtons(entry, installedId) {
 | 
			
		||||
    if (Number(entry)) {
 | 
			
		||||
  function renderActionButtons(entry) {
 | 
			
		||||
    if (typeof entry !== 'object') {
 | 
			
		||||
      entry = $('#' + RESULT_ID_PREFIX + entry);
 | 
			
		||||
    }
 | 
			
		||||
    if (!entry) return;
 | 
			
		||||
    const result = entry._result;
 | 
			
		||||
    if (typeof installedId === 'number') {
 | 
			
		||||
      result._installed = installedId > 0;
 | 
			
		||||
      result._installedStyleId = installedId;
 | 
			
		||||
    }
 | 
			
		||||
    const isInstalled = result._installed;
 | 
			
		||||
    const installedId = result._styleId;
 | 
			
		||||
    const isInstalled = installedId > 0; // must be boolean for comparisons below
 | 
			
		||||
    const status = $('.search-result-status', entry).textContent =
 | 
			
		||||
      isInstalled ? t('clickToUninstall') :
 | 
			
		||||
        entry.dataset.noImage != null ? t('installButton') :
 | 
			
		||||
          '';
 | 
			
		||||
    const notMatching = installedId > 0 && !$entry(installedId);
 | 
			
		||||
    const notMatching = isInstalled && !$entry(installedId);
 | 
			
		||||
    if (notMatching !== entry.classList.contains('not-matching')) {
 | 
			
		||||
      entry.classList.toggle('not-matching');
 | 
			
		||||
      if (notMatching) {
 | 
			
		||||
| 
						 | 
				
			
			@ -456,6 +460,7 @@
 | 
			
		|||
      disabled: notMatching,
 | 
			
		||||
    });
 | 
			
		||||
    toggleDataset(entry, 'installed', isInstalled);
 | 
			
		||||
    toggleDataset(entry, 'customizable', result._styleVars);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  function renderFullInfo(entry, style) {
 | 
			
		||||
| 
						 | 
				
			
			@ -469,17 +474,20 @@
 | 
			
		|||
      textContent: description,
 | 
			
		||||
      title: description,
 | 
			
		||||
    });
 | 
			
		||||
    vars = !isEmptyObj(vars);
 | 
			
		||||
    entry._result._styleVars = vars;
 | 
			
		||||
    toggleDataset(entry, 'customizable', vars);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  function configure() {
 | 
			
		||||
    const styleEntry = $entry($resultEntry(this).result._installedStyleId);
 | 
			
		||||
    const styleEntry = $entry($resultEntry(this).result._styleId);
 | 
			
		||||
    Events.configure.call(this, {target: styleEntry});
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  async function install() {
 | 
			
		||||
    const {entry, result} = $resultEntry(this);
 | 
			
		||||
    const {i: id, f: fmt} = result;
 | 
			
		||||
    const {f: fmt} = result;
 | 
			
		||||
    const id = rid2id(result.i);
 | 
			
		||||
    const installButton = $('.search-result-install', entry);
 | 
			
		||||
 | 
			
		||||
    showSpinner(entry);
 | 
			
		||||
| 
						 | 
				
			
			@ -507,7 +515,7 @@
 | 
			
		|||
  function uninstall() {
 | 
			
		||||
    const {entry, result} = $resultEntry(this);
 | 
			
		||||
    saveScrollPosition(entry);
 | 
			
		||||
    API.styles.delete(result._installedStyleId);
 | 
			
		||||
    API.styles.delete(result._styleId);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  function saveScrollPosition(entry) {
 | 
			
		||||
| 
						 | 
				
			
			@ -553,10 +561,11 @@
 | 
			
		|||
  async function fetchIndex() {
 | 
			
		||||
    const timer = setTimeout(showSpinner, BUSY_DELAY, dom.list);
 | 
			
		||||
    const jobs = [
 | 
			
		||||
      [INDEX_URL, json => json.filter(entry => entry.f === 'uso')],
 | 
			
		||||
      [USW_INDEX_URL, json => json.data],
 | 
			
		||||
    ].map(async ([url, transform]) => {
 | 
			
		||||
      [INDEX_URL, 'uso', json => json.filter(v => v.f === 'uso')],
 | 
			
		||||
      [USW_INDEX_URL, 'usw', json => json.data],
 | 
			
		||||
    ].map(async ([url, prefix, transform]) => {
 | 
			
		||||
      const res = transform(await download(url, {responseType: 'json'}));
 | 
			
		||||
      for (const v of res) v.i = `${prefix}-${v.i}`;
 | 
			
		||||
      index = index ? index.concat(res) : res;
 | 
			
		||||
      if (index !== res) ready = ready.then(start);
 | 
			
		||||
    });
 | 
			
		||||
| 
						 | 
				
			
			@ -607,17 +616,4 @@
 | 
			
		|||
        : b[order] - a[order]
 | 
			
		||||
    ) || b.t - a.t;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  function calcUsoId({md5Url: m, updateUrl}) {
 | 
			
		||||
    return Number(m && m.match(/\d+|$/)[0]) ||
 | 
			
		||||
           URLS.extractUsoArchiveId(updateUrl);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  function calcUswId({updateUrl}) {
 | 
			
		||||
    return URLS.extractUSwId(updateUrl) || 0;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  function calcId(style) {
 | 
			
		||||
    return calcUsoId(style) || calcUswId(style);
 | 
			
		||||
  }
 | 
			
		||||
})();
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in New Issue
	
	Block a user