• Как обернуть img через regexp в ссылку в данном случае?

    @dillix Автор вопроса
    Спасибо! Работает как часы)
  • Какой датацентр выбрать в Москве?

    @dillix Автор вопроса
    Москва нужна)
  • Какой датацентр выбрать в Москве?

    @dillix Автор вопроса
    ky0 Пока вот рассматриваем 2 варианта: webdc (через firstdedic) и selectel (msk), но второй дороже.
  • Где косяк в promise?

    @dillix Автор вопроса
    0xD34F разобрался, да проблема с данными решилась, а проблема комментом выше это из-за webpack. Теперь хоть понятно куда копать, спасибо вам за помощь с промисами!
  • Где косяк в promise?

    @dillix Автор вопроса
    0xD34F, да все верно, спасибо, у меня уже мозг клинит от асинхрона, до этого 10 лет на php кодил... Правильно ли я понимаю что код внутри:
    generateTree(appDataDir).then( tree => {
    ...
    });

    будет выполнен после того как все данные будут получены и переданы в tree?
  • Где косяк в promise?

    @dillix Автор вопроса
    0xD34F, начет каунта понял, а вот если буду делать resolve в колбеке, у меня разве прилетит полный массив treeArr? я же в foreach пробегаюсь по всем файлам чтобы по ним собрать данный массив...
  • Где косяк в promise?

    @dillix Автор вопроса
    0xD34F, обычно говорят callback hell, а у меня promise hell, помогите пожалуйста, я уже второй день бьюсь с этими промисами((
  • Где косяк в promise?

    @dillix Автор вопроса
    0xD34F я пробовал и так переписать, результат тот же:

    const generateTree = (dir) => {
      return getAllFiles(dir, function(f) {
        return path.extname(f) === '.html';
      })
      .then(files => {
        return new Promise(function(resolve, reject) {
          var count = files.length;
          files.forEach(function(file) {
            fs.readFile(file, 'utf-8', function read(err, contents) {
              if (err) throw err;
              if(contents.indexOf('meta content="_index"') !== -1){
                // ToDo: Front pages
        
              } else {
                // All other pages
                let regexp_title = /<title>(.*?)<\/title>/i
                let regexp_chapter = /<meta chapter="(.*?)" order="([0-9]+)">/i
                let data = regexp_chapter.exec(contents);
        
                // Exclude files from algorithm without our metatags
                if(data !== null) {
                  let dataChapter = data[1];
                  let dataTitle = regexp_title.exec(contents)[1];
                  if(dataChapter.indexOf('\\') !== -1) {
                    // Add categories
                    var chapters = dataChapter.split('\\'),
                        parentId = 0,
                        nodePath = '',
                        nodeId;
                    for(var i=0, ilen = chapters.length; i < ilen; i++) {
                      nodePath += (nodePath.length > 0 ? '\\' : '') + chapters[i];
                      nodeId = addNode(nodePath, chapters[i]);
                      if(treeArr[parentId].childs.indexOf(nodeId) === -1) treeArr[parentId].childs.push(nodeId);
                      parentId = nodeId;
                      //console.log(chapters[i]);
                    }
        
                    // Add node & attach it to category
                    nodeId = addNode(nodePath + '\\' + dataTitle, dataTitle, file);
                    treeArr[parentId].childs.push(nodeId);
                  }
                }
              }
            });
    
            count--;
            if (count === 0) {
              resolve(treeArr);
            }
          });
        }).then(function(results) {
          return treeArr;
        });
    
        return treeArr;
      })
      .catch(console.error);
    }
  • Как запустить коллбек после асинхронных функций?

    @dillix Автор вопроса
    Переписал код используя нативные промисы, попутно отрефакторил. Посмотрите правильно ли? И еще вопрос, можно ли теперь const tree вынести за пределы промиса, чтобы к ней имели доступ другие функции?

    let root = {
      name: 'Global',
      file: null,
      children: []
    };
    
    function ipGetTree(folder) {
      return new Promise(function(resolve, reject) {
        fs.readdir(dataFolder, (err, files) => {
          files = files.filter(function(file) {
              return path.extname(file) === '.html';
          });
    
          var count = files.length;
          files.forEach(function(file) {
            fs.readFile(dataFolder+file, 'utf-8', function(err, contents) {
              if(contents.indexOf('meta content="_index"') !== -1){
                // Front pages
    
              } else {
                // All other pages
                let dataChapter = regexp_chapter.exec(contents)[1];
                if(dataChapter.indexOf('\\') !== -1) {
                  let chapters = dataChapter.split('\\');
                  let parentLeaf = null;
                  for(var i=0, ilen = chapters.length; i < ilen; i++) {
                    if(parentLeaf === null) {
                      if(!objTraverse.findFirst(root, 'children', {name:chapters[i]})) {
                        root['children'].push({
                          name:chapters[i],
                          children:[],
                          file:dataChapter
                        });
                      }
                    } else {
                      if(!objTraverse.findFirst(root, 'children', {name:chapters[i]})) {
                        if(objRef = objTraverse.findFirst(root, 'children', {name:parentLeaf})) {
                          objRef['children'].push({
                            name:chapters[i],
                            children:[],
                            file:dataChapter
                          });
                        }
                      }
                    }
                    parentLeaf = chapters[i];
                  }
                }
              }
    
              count--;
              if (count === 0) {
                resolve(root);
              }
            });
          });
        });
      });
    }
    
    ipGetTree(dataFolder).then(function(root) {
      const tree = require('electron-tree-view')({
        root,
        container: document.querySelector('.sidebar'),
        children: c => c.children,
        label: c => c.name
      })
    });
  • Как запустить коллбек после асинхронных функций?

    @dillix Автор вопроса
    Виталий: я вот первый раз с нодой столкнулся, пишу десктопное приложение на Electron, с JS раньше работал, и честно говоря не сразу понял, что грабли у меня были из-за асинхронности... Простые примеры нагуглил, но вот в асинхоне еще и цикл с асинхронной функцией: видимо надо какой-то пул сделать из promise + какую библиотеку лучше взять?
  • Как запустить коллбек после асинхронных функций?

    @dillix Автор вопроса
    Как добавить 1 promise для readdir в принципе понятно, а вот как вложенный сделать к тому же там readFile в цикле сидит, не догоняю...
  • Как проверить на javascript существование свойств у динамического объекта и создать их в случае отсутствия?

    @dillix Автор вопроса
    Alex спасибо, для локальной задачи работает, но вот попробовал встроить в проект и столнулся с проблемой, там получается что на каждой итерации содержимое затирается, вот привожу полный код:

    var regexp_chapter = /<meta chapter="(.*?)" order="([0-9]+)">/i
    var root = {};
    fs.readdir(dataFolder, (err, fileNames) => {
      for (var i = 0, len = fileNames.length; i < len; i++) {
        if(path.extname(fileNames[i]) === '.html'){
          fs.readFile(dataFolder+fileNames[i], (err, data) => {
            var dataChapter = regexp_chapter.exec(data)[1];
            //ToDo add sort by order
            if(dataChapter.indexOf('\\') !== -1){
              let chapters = dataChapter.split('\\');
              let root = makeTree(chapters);
            }
          })
        }
      }
    })
  • Как проверить на javascript существование свойств у динамического объекта и создать их в случае отсутствия?

    @dillix Автор вопроса
    Jman, у меня данный код лежит внутри другого цикла, кроме строки var root = {}. В вашем коде не хватает проверки связанной с root и глубина на каждой итерации цикла должна увеличиваться для этого использовал строки, но как их конвертировать в вызов объекта и его дочерних свойств я не разобрался...
  • Как проверить на javascript существование свойств у динамического объекта и создать их в случае отсутствия?

    @dillix Автор вопроса
    Николай, вот что пытаюсь сделать:
    мне надо на каждой итерации проверять существует ли name на текущем уровне, если не существует, то добавлять его и создавать children для следующей итерации.
  • Как через xpath добраться до середины текста на php?

    @dillix Автор вопроса
    Спасибо, именно этого кусочка мне не хватало, а понятной иформации по xpath не нашел((
  • Как через xpath добраться до середины текста на php?

    @dillix Автор вопроса
    Ilya: Я практически решил задачу, но осталась проблема отсечь абзацы, находящиеся в теге blockquote. Вот пример, того что получилось:
    $html = <<< EOT
    <p>1. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vestibulum rutrum metus rutrum leo rutrum, pretium luctus urna accumsan. Morbi bibendum dolor dolor, et dictum ex sollicitudin a. Aliquam eget enim risus. Vestibulum lacus ligula, ultricies ut dictum eu, varius sed nibh. Nam nunc risus, maximus eget venenatis sed, tempus sit amet nunc. Nulla posuere porttitor cursus. Aenean eget convallis orci. Quisque eget fermentum libero. Aliquam sed massa ornare, consequat enim nec, convallis libero. Vivamus feugiat quam sed venenatis tempor. Praesent placerat nibh tristique, aliquet odio nec, mollis quam. Quisque laoreet vestibulum tincidunt.</p>
    <p>2. Sed a aliquet elit. Quisque convallis feugiat enim eu gravida. Nulla a aliquam nunc. In venenatis augue cursus interdum ultrices. Sed volutpat lorem volutpat velit venenatis, ut dapibus mi viverra. In luctus turpis magna, a faucibus lectus placerat eget. Ut non elementum dui. Maecenas ut dignissim mauris, a fermentum arcu. Pellentesque et elit sed diam suscipit placerat et sit amet massa. Vestibulum porta id leo sed cursus. Quisque quis fringilla libero. Vestibulum blandit, lectus et ultricies commodo, ligula metus lobortis purus, at blandit nisi est nec urna. Integer venenatis urna id arcu hendrerit, sed ultrices nisl ullamcorper. Ut odio ex, mollis a purus ac, dapibus congue mi. Quisque cursus nulla in velit laoreet elementum.</p>
    <p>3. Fusce turpis justo, pellentesque ac blandit sed, egestas a mi. Donec eget condimentum nunc, maximus tincidunt sem. Cras sed malesuada enim, id feugiat purus. Suspendisse finibus vulputate velit nec venenatis. Nunc ornare lectus nibh, a suscipit sapien ornare et. Etiam pulvinar, enim sed posuere mollis, libero nunc imperdiet lectus, non dapibus quam risus ac est. Quisque lobortis nisl id hendrerit bibendum. In nec bibendum odio. Nulla pharetra ante fermentum, tempus elit sed, rhoncus metus. Pellentesque et purus mattis, aliquam libero sed, scelerisque metus. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Nullam eget metus augue. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Ut viverra, libero ac commodo porta, justo lacus tristique ipsum, vitae sagittis eros felis at est. In efficitur a sem laoreet ultricies.</p>
    <p>4. Morbi iaculis eleifend erat, vitae efficitur urna tristique congue. Ut ac faucibus quam. Interdum et malesuada fames ac ante ipsum primis in faucibus. Praesent convallis accumsan finibus. Integer sagittis quam nec libero consequat, sed hendrerit est blandit. Curabitur maximus lectus justo, sit amet pretium orci pharetra quis. Integer consequat, arcu sed rhoncus scelerisque, ante mauris placerat nulla, et bibendum ante ante eget eros. In dictum, diam ut feugiat venenatis, lacus arcu vestibulum arcu, sit amet lacinia velit lorem at leo. Aenean egestas lectus purus, hendrerit convallis est eleifend efficitur. Quisque id viverra enim. Etiam sagittis lorem et massa facilisis vehicula. Fusce porta leo a libero pellentesque ornare vel sed quam. Vestibulum iaculis erat tellus, at aliquet nunc tincidunt eu. Aenean ac metus at augue bibendum lacinia ac non ipsum. Fusce iaculis ex id magna ornare aliquet. Suspendisse potenti.</p>
    <p>5. Integer justo velit, mattis vel justo a, elementum blandit lectus. Curabitur mollis mi sit amet mattis interdum. Praesent congue pulvinar nisl sed tempus. Phasellus tincidunt efficitur posuere. Vestibulum iaculis nulla eget massa pretium vestibulum. Morbi ultrices mattis sodales. Aliquam sit amet ipsum quis justo fringilla sollicitudin in sed dui. Fusce quis magna viverra, eleifend urna vitae, facilisis dui. In molestie augue ligula. Aliquam vel odio luctus, suscipit risus at, mattis nunc.</p>
    <p>6. Vestibulum finibus eu leo vel auctor. Proin purus ex, interdum ac tempor non, sollicitudin efficitur est. Nunc congue augue eu tellus volutpat, vitae tempor quam convallis. Morbi faucibus lacus et feugiat suscipit. Nulla sagittis est commodo urna cursus, at iaculis nibh facilisis. Nulla eu auctor neque, sed vestibulum lectus. Nam et libero eu justo euismod finibus. Donec ac eros a massa condimentum fermentum a et velit. Cras a gravida mi, eu facilisis ligula. Pellentesque ac ligula finibus, convallis nibh non, molestie nibh. Mauris aliquet pharetra quam quis suscipit. Nulla convallis massa in tincidunt ullamcorper. Ut vel velit eget risus venenatis efficitur.</p>
    <p>7. Nam ut mauris efficitur turpis pretium pretium. Quisque non urna mattis velit tristique molestie eget nec lacus. Praesent sit amet ligula justo. Ut est lacus, tempus quis placerat vulputate, mollis id ipsum. Aenean leo sapien, porta vel enim nec, dignissim pharetra augue. Maecenas mattis vehicula turpis, eu pellentesque urna lobortis a. In sed varius neque. Ut nec hendrerit ipsum. Fusce vehicula semper velit ac condimentum. Praesent mattis, est non lobortis cursus, sem sem fringilla turpis, et dapibus sem tellus nec quam. Quisque id pellentesque mauris, et varius diam.</p>
    <h2>Торнадо</h2>
    <blockquote>
    <p>8.1. Curabitur faucibus lectus placerat nibh egestas, at ultrices purus faucibus.</p>
    </blockquote>
    <p>8. Curabitur faucibus lectus placerat nibh egestas, at ultrices purus faucibus. Duis scelerisque iaculis odio eget blandit. Cras erat dolor, interdum non dolor non, euismod pellentesque sapien. Aliquam vulputate odio at elit porta commodo. Donec eu metus velit. Aliquam sollicitudin ornare mi sed dictum. Nullam feugiat egestas urna, id egestas sapien vehicula quis. In sollicitudin velit eget dui convallis congue. Cras id risus in ex euismod ultricies id viverra enim.</p>
    <p>9. Quisque a porta quam. Mauris rutrum felis dui, sit amet laoreet nisl euismod vel. In a vestibulum orci. Morbi blandit augue ut vestibulum porttitor. Maecenas lacinia porta elementum. Sed erat metus, viverra vitae congue et, sodales in mauris. Integer non aliquet augue. In feugiat consectetur libero ac commodo. Cras enim magna, aliquet non augue non, convallis faucibus ante. Duis semper aliquet justo in gravida. Sed nec efficitur felis, eget consequat felis. Nulla facilisi.</p>
    <p>10. Aliquam condimentum, mauris nec sodales aliquet, justo elit suscipit leo, ac facilisis sem arcu at risus. Pellentesque et fermentum sapien. Nunc ut odio a metus rutrum faucibus in nec massa. Etiam efficitur est in ex pellentesque sollicitudin vel a quam. Praesent urna neque, interdum eget ex ac, dignissim semper orci. Donec pellentesque lectus quis eros lacinia venenatis. Donec cursus elit id justo cursus, quis aliquet dolor ullamcorper. Vivamus et elit semper, tincidunt odio eget, auctor urna. Suspendisse a vulputate dolor. Nulla convallis viverra consequat. Duis dignissim lectus nisl, viverra iaculis elit euismod at. Suspendisse tincidunt euismod justo vitae viverra. Sed tincidunt non odio vel pulvinar.</p>
    <p>11. Vivamus sodales dignissim elit, cursus sodales lacus bibendum id. Nunc sodales blandit purus, sed molestie nulla vulputate id. Cras mattis, quam vitae condimentum ullamcorper, leo purus ultricies orci, vel consectetur neque tellus condimentum mauris. Maecenas aliquam tellus at nibh cursus tristique. Curabitur in tempus elit. Duis eget fermentum elit, vel suscipit urna. Cras venenatis a eros pulvinar lobortis. Proin hendrerit mattis vehicula. Donec tempor urna sed dolor maximus, at mollis neque viverra. Morbi viverra libero id mauris dictum, ac feugiat nunc rhoncus. Proin efficitur bibendum justo in condimentum.</p>
    EOT;
    $doc = new DOMDocument('1.0', 'UTF-8');
    $fragment = $doc->createDocumentFragment();
    $fragment->appendXML($html);
    $doc->appendChild($fragment);
    $xpath = new DOMXPath($doc);
    $element = $xpath->query('//p[position() = floor(last() div 2 + 0.5) or position() = ceiling(last() div 2 + 0.5)]')->item(0);
    
    $ads = $doc->createElement('p', 'Ads will be here');
    $element->parentNode->insertBefore($ads, $element->nextSibling);
    
    header('Content-Type: text/plain');
    print $doc->saveHTML();
  • Как заменить preg_replace на preg_replace_callback?

    @dillix Автор вопроса
    Melkij спасибо! Про use не знал
  • Как заменить preg_replace на preg_replace_callback?

    @dillix Автор вопроса
    Melkij А в конце регулярки /imeu или /imu?