{"version":3,"sources":["https://lively-kernel.org/lively4/lively4-leo/src/components/tools/lively-generic-search.js"],"names":["Morph","FileIndex","pt","LivelyGenericSearch","input","get","outer","inner","list","initialize","windowTitle","startSearching","calculateListToShow","throttle","setupInput","lively","html","registerKeys","addEventListener","close","evt","onClick","init","onKeyInput","inputChanged","remove","e","keyActions","Map","jumpToSelectedItem","getOrCreate","keyCode","onUpDown","stopPropagation","preventDefault","currentItem","nextItem","previousElementSibling","getAllSubmorphs","last","classList","add","onDownDown","nextElementSibling","first","jumpToItem","item","openBrowser","getAttribute","shiftKey","composedPath","find","ea","contains","setFocus","focus","setPosition","files","getFiles","searchRoots","_roots","preferences","result","current","db","each","file","push","pattern","value","search","RegExp","filteredFiles","filter","url","startsWith","lively4url","relativePath","replace","match","inSearchRoot","cutFiles","slice","updateList","filesToDisplay","innerHTML","forEach","name","length","regex","text","realResult","realStart","counter","exec","start","index","l","normal","substring","highlight","appendChild","querySelector","onKeyDown","livelyPreMigrate","livelyMigrate","other","livelyInspect","contentNode","inspector"],"mappings":"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","file":"lively-generic-search.js","sourcesContent":["import Morph from 'src/components/widgets/lively-morph.js';\nimport FileIndex from \"src/client/fileindex.js\";\nimport { pt } from 'src/client/graphics.js';\n\nexport default class LivelyGenericSearch extends Morph {\n  get input() { return this.get('#input'); }\n  get outer() { return this.get('#outer'); }\n  get inner() { return this.get('#inner'); }\n  get list() { return this.get('#list'); }\n  \n  // #TODO: mark as meta\n  async initialize() {\n    this.windowTitle = \"LivelyGenericSearch\";\n\n    this.startSearching = (() => this.calculateListToShow()).throttle(300);\n    this.setupInput();\n\n    lively.html.registerKeys(this); // automatically installs handler for some methods\n\n    this.addEventListener(\"focusout\", () => this.close())\n    this.addEventListener(\"click\", evt => this.onClick(evt))\n    this.init()\n  }\n    \n  setupInput() {\n    this.input.addEventListener(\"keyup\", evt => {\n      this.onKeyInput(evt);\n    });\n    this.input.addEventListener('input', evt => this.inputChanged(evt));\n  }\n\n  inputChanged(evt) {\n    // lively.success('input is now ${this.input.value}', evt)\n    this.startSearching()\n  }\n  \n  close() {\n    try {\n      this.remove()\n    } catch(e) {\n      // no errors please..\n    }\n  }\n  \n  onKeyInput(evt) {\n    const keyActions = new Map([\n      [13, evt => {\n        this.jumpToSelectedItem(evt);\n        this.close();\n      }], // ENTER\n      [27, evt => this.close()], // ESCAPE\n    ]);\n    \n    keyActions.getOrCreate(evt.keyCode, keyCode => evt => {})(evt);\n  }\n  \n  onUpDown(evt) {\n    evt.stopPropagation();\n    evt.preventDefault();\n\n    const currentItem = this.get('.selected')\n    if (!currentItem) { return; }\n    \n    const nextItem = currentItem.previousElementSibling || this.getAllSubmorphs('.item').last;\n    if(!nextItem) { return; }\n    \n    currentItem.classList.remove('selected')\n    nextItem.classList.add('selected')\n  }\n  onDownDown(evt) {\n    evt.stopPropagation();\n    evt.preventDefault();\n    \n    const currentItem = this.get('.selected')\n    if (!currentItem) { return; }\n    \n    var nextItem = currentItem.nextElementSibling || this.getAllSubmorphs('.item').first;\n    if(!nextItem) { return; }\n    \n    currentItem.classList.remove('selected')\n    nextItem.classList.add('selected')\n  }\n  \n  async jumpToSelectedItem(evt) {\n    this.jumpToItem(this.get('.selected'), evt)\n  }\n  \n  async jumpToItem(item, evt) {\n    if (!item) return\n    lively.openBrowser(item.getAttribute('file'), !evt.shiftKey);\n    this.close()\n  }\n  \n  \n  onClick(evt) {\n    var item =  evt.composedPath().find(ea => ea.classList.contains(\"item\"))\n    this.jumpToItem(item, evt)\n  }\n  \n  setFocus() {\n    this.input.focus();\n  }\n  init() {\n    lively.setPosition(this, pt(500, 100), 'fixed')\n    this.files = this.getFiles();\n    this.startSearching();\n  }\n\n  get searchRoots() {\n    if (!this._roots) {\n      this._roots = lively.preferences.get(\"ExtraSearchRoots\") \n    } \n    return this._roots\n  }\n  \n  async getFiles() {\n    var result = [];\n    await FileIndex.current().db.files.each(file => result.push(file));\n    return result;\n  }\n  \n  async calculateListToShow() {\n    var pattern = this.input.value;\n    var search = new RegExp(pattern, 'ig');\n\n    const filteredFiles = (await this.files).filter(file => {\n      if (file.url.startsWith(lively4url)) {\n        const relativePath = file.url.replace(/.*\\//ig, '');\n        return relativePath.match(search);\n      } else {\n        var inSearchRoot = this.searchRoots.find(ea => file.url.startsWith(ea)) \n        if (inSearchRoot) {\n          const relativePath = file.url.replace(/.*\\//ig, '');\n          return relativePath.match(search);\n        }\n        return false;\n      }\n    });\n    \n    const cutFiles = filteredFiles.slice(0, 50);\n    this.updateList(cutFiles);\n  }\n  async updateList(filesToDisplay) {\n    this.list.innerHTML = '';\n    filesToDisplay = filesToDisplay.slice(0,50)\n    \n    filesToDisplay.forEach(file => {\n      let name = file.url\n      var inSearchRoot = this.searchRoots.find(ea => file.url.startsWith(ea)) \n      if (inSearchRoot) {\n        name = name.replace(inSearchRoot, '')\n      } else {\n        name = name.replace(lively4url, '')        \n      }\n      \n      if (this.input.value.length >= 3) {\n        var regex = new RegExp(this.input.value, 'ig')\n        var text = name;\n        const realResult = [];\n        var result;\n        var realStart = 0\n        var counter = 0\n        while((result = regex.exec(text)) !== null) {\n          var start = result.index\n          var l = result[0].length\n\n          var normal = <span>{text.substring(realStart, start)}</span>\n          var highlight = <span style=\"color: red\">{result[0]}</span>\n              realResult.push(normal)\n              realResult.push(highlight)\n          realStart = start+l\n          if (counter++ > 10) {break;}\n        }\n        realResult.push(<span>{text.substring(realStart, text.length)}</span>)\n\n\n        this.list.appendChild(<div class=\"item\" file={file.url}><span>{...realResult}</span></div>); \n      } else {\n        this.list.appendChild(<div class=\"item\" file={file.url}><span>{name}</span></div>); \n      }\n    });\n    const first = this.list.querySelector('.item')\n    if (first) {\n      first.classList.add('selected');\n    }\n  }\n  \n  // this method is autmatically registered through the ``registerKeys`` method\n  onKeyDown(evt) {\n    // lively.notify(\"Key Down: \" + evt.charCode)\n  }\n  \n  livelyPreMigrate() {\n    // is called on the old object before the migration\n  }\n  \n  livelyMigrate(other) {\n    // whenever a component is replaced with a newer version during development\n    // this method is called on the new object during migration, but before initialization\n    this.input.value = other.input.value;\n    this.input.focus();\n  }\n  \n  livelyInspect(contentNode, inspector) {\n    // do nothing\n  }\n}"]}