Exemplo n.º 1
0
void HTMLConstructionSite::flushPendingText()
{
    if (m_pendingText.isEmpty())
        return;

    PendingText pendingText;
    // Hold onto the current pending text on the stack so that queueTask doesn't recurse infinitely.
    m_pendingText.swap(pendingText);
    ASSERT(m_pendingText.isEmpty());

    // Splitting text nodes into smaller chunks contradicts HTML5 spec, but is necessary
    // for performance, see: https://bugs.webkit.org/show_bug.cgi?id=55898
    unsigned lengthLimit = textLengthLimitForContainer(*pendingText.parent);

    unsigned currentPosition = 0;
    const StringBuilder& string = pendingText.stringBuilder;
    while (currentPosition < string.length()) {
        unsigned proposedBreakIndex = std::min(currentPosition + lengthLimit, string.length());
        unsigned breakIndex = findBreakIndexBetween(string, currentPosition, proposedBreakIndex);
        ASSERT(breakIndex <= string.length());
        String substring = string.substring(currentPosition, breakIndex - currentPosition);
        substring = atomizeIfAllWhitespace(substring, pendingText.whitespaceMode);

        HTMLConstructionSiteTask task(HTMLConstructionSiteTask::InsertText);
        task.parent = pendingText.parent;
        task.child = Text::create(task.parent->document(), substring);
        queueTask(task);

        ASSERT(breakIndex > currentPosition);
        ASSERT(breakIndex - currentPosition == substring.length());
        ASSERT(toText(task.child.get())->length() == substring.length());
        currentPosition = breakIndex;
    }
}
Exemplo n.º 2
0
void HTMLConstructionSite::attachLater(ContainerNode* parent, PassRefPtr<Node> prpChild, bool selfClosing)
{
    HTMLConstructionSiteTask task(HTMLConstructionSiteTask::Insert);
    task.parent = parent;
    task.child = prpChild;
    task.selfClosing = selfClosing;

    // Add as a sibling of the parent if we have reached the maximum depth allowed.
    if (m_openElements.stackDepth() > maximumHTMLParserDOMTreeDepth && task.parent->parentNode())
        task.parent = task.parent->parentNode();

    ASSERT(task.parent);
    queueTask(task);
}
Exemplo n.º 3
0
void HTMLConstructionSite::flushPendingText()
{
    if (m_pendingText.isEmpty())
        return;

    PendingText pendingText;
    // Hold onto the current pending text on the stack so that queueTask doesn't recurse infinitely.
    m_pendingText.swap(pendingText);
    ASSERT(m_pendingText.isEmpty());

    // Splitting text nodes into smaller chunks contradicts HTML5 spec, but is necessary
    // for performance, see: https://bugs.webkit.org/show_bug.cgi?id=55898
    unsigned lengthLimit = textLengthLimitForContainer(*pendingText.parent);

    unsigned currentPosition = 0;
    const StringBuilder& string = pendingText.stringBuilder;
    while (currentPosition < string.length()) {
        unsigned proposedBreakIndex = std::min(currentPosition + lengthLimit, string.length());
        unsigned breakIndex = findBreakIndexBetween(string, currentPosition, proposedBreakIndex);
        ASSERT(breakIndex <= string.length());
        String substring = string.substring(currentPosition, breakIndex - currentPosition);

        ASSERT(breakIndex > currentPosition);
        ASSERT(breakIndex - currentPosition == substring.length());
        currentPosition = breakIndex;

        if (isAllWhitespace(substring)) {
            // Ignore whitespace nodes not inside inside a <t>. If we're splitting
            // a text node this isn't really a whitespace node and we can't ignore
            // it either.
            if (!m_openElements.preserveWhiteSpace() && string.length() == substring.length())
                continue;

            // Strings composed entirely of whitespace are likely to be repeated.
            // Turn them into AtomicString so we share a single string for each.
            substring = AtomicString(substring).string();
        }

        HTMLConstructionSiteTask task(HTMLConstructionSiteTask::InsertText);
        task.parent = pendingText.parent;
        task.child = Text::create(task.parent->document(), substring);
        queueTask(task);
        ASSERT(toText(task.child.get())->length() == substring.length());
    }
}
Exemplo n.º 4
0
void LibraryScanner::slotStartScan() {
    qDebug() << "LibraryScanner::slotStartScan";
    QSet<QString> trackLocations = m_trackDao.getTrackLocations();
    QHash<QString, int> directoryHashes = m_libraryHashDao.getDirectoryHashes();
    QRegExp extensionFilter =
            QRegExp(SoundSourceProxy::supportedFileExtensionsRegex(),
                    Qt::CaseInsensitive);
    QRegExp coverExtensionFilter =
            QRegExp(CoverArtUtils::supportedCoverArtExtensionsRegex(),
                    Qt::CaseInsensitive);
    QStringList directoryBlacklist = ScannerUtil::getDirectoryBlacklist();

    m_scannerGlobal = ScannerGlobalPointer(
        new ScannerGlobal(trackLocations, directoryHashes, extensionFilter,
                          coverExtensionFilter, directoryBlacklist));
    m_scannerGlobal->startTimer();

    emit(scanStarted());

    // Try to upgrade the library from 1.7 (XML) to 1.8+ (DB) if needed. If the
    // upgrade_filename already exists, then do not try to upgrade since we have
    // already done it.
    // TODO(XXX) SETTINGS_PATH may change in new Mixxx Versions. Here we need
    // the SETTINGS_PATH from Mixxx V <= 1.7
    QString upgrade_filename = QDir::homePath().append("/").append(SETTINGS_PATH).append("DBUPGRADED");
    qDebug() << "upgrade filename is " << upgrade_filename;
    QFile upgradefile(upgrade_filename);
    if (!upgradefile.exists()) {
        QTime t2;
        t2.start();
        LegacyLibraryImporter libImport(m_trackDao, m_playlistDao);
        connect(&libImport, SIGNAL(progress(QString)),
                this, SIGNAL(progressLoading(QString)));
        ScopedTransaction transaction(m_database);
        libImport.import();
        transaction.commit();
        qDebug("Legacy importer took %d ms", t2.elapsed());
    }

    // First, we're going to mark all the directories that we've previously
    // hashed as needing verification. As we search through the directory tree
    // when we rescan, we'll mark any directory that does still exist as
    // verified.
    m_libraryHashDao.invalidateAllDirectories();

    // Mark all the tracks in the library as needing verification of their
    // existence. (ie. we want to check they're still on your hard drive where
    // we think they are)
    m_trackDao.invalidateTrackLocationsInLibrary();

    qDebug() << "Recursively scanning library.";

    // Start scanning the library. This prepares insertion queries in TrackDAO
    // (must be called before calling addTracksAdd) and begins a transaction.
    m_trackDao.addTracksPrepare();

    // Recursivly scan each directory in the directories table.
    QStringList dirs = m_directoryDao.getDirs();

    // If there are no directories then we have nothing to do. Cleanup and
    // finish the scan immediately.
    if (dirs.isEmpty()) {
        slotFinishScan();
        return;
    }

    // Queue up recursive scan tasks for every directory. When all tasks are
    // done, TaskWatcher will signal slotFinishScan.
    TaskWatcher* pWatcher = &m_scannerGlobal->getTaskWatcher();
    connect(pWatcher, SIGNAL(allTasksDone()),
            this, SLOT(slotFinishScan()));

    foreach (const QString& dirPath, dirs) {
        // Acquire a security bookmark for this directory if we are in a
        // sandbox. For speed we avoid opening security bookmarks when recursive
        // scanning so that relies on having an open bookmark for the containing
        // directory.
        MDir dir(dirPath);

        queueTask(new RecursiveScanDirectoryTask(this, m_scannerGlobal, dir.dir(),
                                                 dir.token()));
    }
Exemplo n.º 5
0
void LibraryScanner::slotStartScan() {
    qDebug() << "LibraryScanner::slotStartScan";
    DEBUG_ASSERT(m_state == STARTING);

    // Recursively scan each directory in the directories table.
    m_libraryRootDirs = m_directoryDao.getDirs();
    // If there are no directories then we have nothing to do. Cleanup and
    // finish the scan immediately.
    if (m_libraryRootDirs.isEmpty()) {
        changeScannerState(IDLE);
        return;
    }
    changeScannerState(SCANNING);

    QSet<QString> trackLocations = m_trackDao.getTrackLocations();
    QHash<QString, int> directoryHashes = m_libraryHashDao.getDirectoryHashes();
    QRegExp extensionFilter(SoundSourceProxy::getSupportedFileNamesRegex());
    QRegExp coverExtensionFilter =
            QRegExp(CoverArtUtils::supportedCoverArtExtensionsRegex(),
                    Qt::CaseInsensitive);
    QStringList directoryBlacklist = ScannerUtil::getDirectoryBlacklist();

    m_scannerGlobal = ScannerGlobalPointer(
            new ScannerGlobal(trackLocations, directoryHashes, extensionFilter,
                              coverExtensionFilter, directoryBlacklist));

    m_scannerGlobal->startTimer();

    emit(scanStarted());

    // First, we're going to mark all the directories that we've previously
    // hashed as needing verification. As we search through the directory tree
    // when we rescan, we'll mark any directory that does still exist as
    // verified.
    m_libraryHashDao.invalidateAllDirectories();

    // Mark all the tracks in the library as needing verification of their
    // existence. (ie. we want to check they're still on your hard drive where
    // we think they are)
    m_trackDao.invalidateTrackLocationsInLibrary();

    qDebug() << "Recursively scanning library.";

    // Start scanning the library. This prepares insertion queries in TrackDAO
    // (must be called before calling addTracksAdd) and begins a transaction.
    m_trackDao.addTracksPrepare();

    // First Scan all known directories we have a hash for.
    // In a second stage, we scan all new directories. This guarantees,
    // that we discover always the same folder, in case of duplicated folders
    // by symlinks

    // Queue up recursive scan tasks for every hashed directory. When all tasks
    // are done, TaskWatcher will signal slotFinishHashedScan.
    TaskWatcher* pWatcher = &m_scannerGlobal->getTaskWatcher();
    pWatcher->watchTask();
    connect(pWatcher, SIGNAL(allTasksDone()),
            this, SLOT(slotFinishHashedScan()));

    foreach (const QString& dirPath, m_libraryRootDirs) {
        // Acquire a security bookmark for this directory if we are in a
        // sandbox. For speed we avoid opening security bookmarks when recursive
        // scanning so that relies on having an open bookmark for the containing
        // directory.
        MDir dir(dirPath);
        if (!m_scannerGlobal->testAndMarkDirectoryScanned(dir.dir())) {
            queueTask(new RecursiveScanDirectoryTask(this, m_scannerGlobal,
                                                     dir.dir(),
                                                     dir.token(),
                                                     false));
        }
    }