Exemplo n.º 1
0
TEST_F(CustomElementRegistryTest,
       collectCandidates_shouldOnlyIncludeCandidatesMatchingDescriptor) {
  CustomElementDescriptor descriptor("hello-world", "hello-world");

  // Does not match: namespace is not HTML
  Element* elementA = CreateElement("hello-world")
                          .inDocument(&document())
                          .inNamespace("data:text/date,1981-03-10");
  // Matches
  Element* elementB = CreateElement("hello-world").inDocument(&document());
  // Does not match: local name is not hello-world
  Element* elementC = CreateElement("button")
                          .inDocument(&document())
                          .withIsAttribute("hello-world");
  document().documentElement()->appendChild(elementA);
  elementA->appendChild(elementB);
  elementA->appendChild(elementC);

  registry().addCandidate(elementA);
  registry().addCandidate(elementB);
  registry().addCandidate(elementC);

  HeapVector<Member<Element>> elements;
  collectCandidates(descriptor, &elements);

  EXPECT_EQ(1u, elements.size())
      << "only one candidates should have been found";
  EXPECT_EQ(elementB, elements[0])
      << "the matching element should have been found";
}
Exemplo n.º 2
0
TEST_F(CustomElementRegistryTest, collectCandidates_oneCandidate) {
  Element* element = CreateElement("a-a").inDocument(&document());
  registry().addCandidate(element);
  document().documentElement()->appendChild(element);

  HeapVector<Member<Element>> elements;
  collectCandidates(CustomElementDescriptor("a-a", "a-a"), &elements);

  EXPECT_EQ(1u, elements.size())
      << "exactly one candidate should have been found";
  EXPECT_TRUE(elements.contains(element))
      << "the candidate should be the element that was added";
}
Exemplo n.º 3
0
TEST_F(CustomElementRegistryTest,
       collectCandidates_shouldNotIncludeElementsRemovedFromDocument) {
  Element* element = CreateElement("a-a").inDocument(&document());
  registry().addCandidate(element);

  HeapVector<Member<Element>> elements;
  collectCandidates(CustomElementDescriptor("a-a", "a-a"), &elements);

  EXPECT_TRUE(elements.isEmpty())
      << "no candidates should have been found, but we have "
      << elements.size();
  EXPECT_FALSE(elements.contains(element))
      << "the out-of-document candidate should not have been found";
}
Exemplo n.º 4
0
TEST_F(CustomElementRegistryTest,
       collectCandidates_shouldNotIncludeElementsInDifferentDocument) {
  Element* element = CreateElement("a-a").inDocument(&document());
  registry().addCandidate(element);

  Document* otherDocument = HTMLDocument::create();
  otherDocument->appendChild(element);
  EXPECT_EQ(otherDocument, element->ownerDocument())
      << "sanity: another document should have adopted an element on append";

  HeapVector<Member<Element>> elements;
  collectCandidates(CustomElementDescriptor("a-a", "a-a"), &elements);

  EXPECT_TRUE(elements.isEmpty())
      << "no candidates should have been found, but we have "
      << elements.size();
  EXPECT_FALSE(elements.contains(element))
      << "the adopted-away candidate should not have been found";
}
Exemplo n.º 5
0
TEST_F(CustomElementRegistryTest, collectCandidates_shouldBeInDocumentOrder) {
  CreateElement factory = CreateElement("a-a");
  factory.inDocument(&document());
  Element* elementA = factory.withId("a");
  Element* elementB = factory.withId("b");
  Element* elementC = factory.withId("c");

  registry().addCandidate(elementB);
  registry().addCandidate(elementA);
  registry().addCandidate(elementC);

  document().documentElement()->appendChild(elementA);
  elementA->appendChild(elementB);
  document().documentElement()->appendChild(elementC);

  HeapVector<Member<Element>> elements;
  collectCandidates(CustomElementDescriptor("a-a", "a-a"), &elements);

  EXPECT_EQ(elementA, elements[0].get());
  EXPECT_EQ(elementB, elements[1].get());
  EXPECT_EQ(elementC, elements[2].get());
}
Exemplo n.º 6
0
// http://w3c.github.io/webcomponents/spec/custom/#dfn-element-definition
void CustomElementRegistry::define(const AtomicString& name,
                                   CustomElementDefinitionBuilder& builder,
                                   const ElementDefinitionOptions& options,
                                   ExceptionState& exceptionState) {
  if (!builder.checkConstructorIntrinsics())
    return;

  if (throwIfInvalidName(name, exceptionState))
    return;

  if (nameIsDefined(name) || v0NameIsDefined(name)) {
    exceptionState.throwDOMException(
        NotSupportedError,
        "this name has already been used with this registry");
    return;
  }

  if (!builder.checkConstructorNotRegistered())
    return;

  // Step 7. customized built-in elements definition
  // element interface extends option checks
  if (RuntimeEnabledFeatures::customElementsBuiltinEnabled() &&
      options.hasExtends()) {
    // If element interface is valid custom element name, throw exception
    if (throwIfValidName(AtomicString(options.extends()), exceptionState))
      return;
    // If element interface is undefined element, throw exception
    // Set localname to extends
  }

  // TODO(dominicc): Add a test where the prototype getter destroys
  // the context.

  // 8. If this CustomElementRegistry's element definition is
  // running flag is set, then throw a "NotSupportedError"
  // DOMException and abort these steps.
  if (m_elementDefinitionIsRunning) {
    exceptionState.throwDOMException(
        NotSupportedError, "an element definition is already being processed");
    return;
  }

  {
    // 9. Set this CustomElementRegistry's element definition is
    // running flag.
    ElementDefinitionIsRunning defining(m_elementDefinitionIsRunning);

    // 10.1-2
    if (!builder.checkPrototype())
      return;

    // 10.3-6
    if (!builder.rememberOriginalProperties())
      return;

    // "Then, perform the following substep, regardless of whether
    // the above steps threw an exception or not: Unset this
    // CustomElementRegistry's element definition is running
    // flag."
    // (ElementDefinitionIsRunning destructor does this.)
  }

  CustomElementDescriptor descriptor(name, name);
  CustomElementDefinition* definition = builder.build(descriptor);
  CHECK(!exceptionState.hadException());
  CHECK(definition->descriptor() == descriptor);
  DefinitionMap::AddResult result =
      m_definitions.add(descriptor.name(), definition);
  CHECK(result.isNewEntry);

  HeapVector<Member<Element>> candidates;
  collectCandidates(descriptor, &candidates);
  for (Element* candidate : candidates)
    definition->enqueueUpgradeReaction(candidate);

  // 16: when-defined promise processing
  const auto& entry = m_whenDefinedPromiseMap.find(name);
  if (entry == m_whenDefinedPromiseMap.end())
    return;
  entry->value->resolve();
  m_whenDefinedPromiseMap.remove(entry);
}
Exemplo n.º 7
0
std::map<int, std::vector<CaptionStart>>
extractCaptionsFromText(const std::vector<TextPage *> &textPages,
                        bool verbose) {
  CandidateCollection candidates = collectCandidates(textPages);
  // In order to be considered
  ColonOnly f1 = ColonOnly();
  PeriodOnly f2 = PeriodOnly();
  BoldOnly f3 = BoldOnly();
  ItalicOnly f4 = ItalicOnly();
  AllCapsFiguresOnly f5 = AllCapsFiguresOnly();
  AbbrevFiguresOnly f6 = AbbrevFiguresOnly();
  NoNextWord f7 = NoNextWord();
  BlockStartOnly f8 = BlockStartOnly();
  LineStartOnly f9 = LineStartOnly();
  NextWordOnly f10 = NextWordOnly();
  std::vector<CandidateFilter *> filters = {&f1, &f2, &f3, &f4, &f5,
                                            &f6, &f7, &f8, &f9, &f10};

  if (verbose) {
    printf("Scanning for captions...\n");
    int nCandidates = 0;
    for (auto &ccs : candidates) {
      nCandidates += ccs.second->size();
    }
    printf("Collected %d candidates for %d detected captions\n", nCandidates,
           (int)candidates.size());
  }

  bool triedAll = false;
  while (anyDuplicates(candidates) and not triedAll) {
    triedAll = true;
    for (CandidateFilter *cf : filters) {
      if (applyFilter(cf, candidates)) {
        if (verbose) {
          int nCandidates = 0;
          for (auto &ccs : candidates) {
            nCandidates += ccs.second->size();
          }
          printf("Applied filter %s (%d remain)\n", cf->name, nCandidates);
        }
        triedAll = false;
        break;
      }
    }
  }

  // Check for non consecutive figures / tables, add any found as errors
  if (verbose) {
    int maxTable = 0;
    int maxFigure = 0;
    int nTables = 0;
    int nFigures = 0;
    for (auto &ccs : candidates) {
      if (ccs.first > 0) {
        nFigures++;
        maxFigure = std::max(ccs.first, maxFigure);
      } else {
        nTables++;
        maxTable = std::max(-ccs.first, maxTable);
      }
    }
    if (maxTable != nTables) {
      printf("Warning: Max table number found was %d, but only found %d table "
             "captions!\n",
             maxTable, nTables);
    }
    if (maxFigure != nFigures) {
      printf(
          "Warning: Max figure number found was %d, but only found %d figure "
          "captions!\n",
          maxFigure, nFigures);
    }
  }

  std::map<int, std::vector<CaptionStart>> output =
      std::map<int, std::vector<CaptionStart>>();

  // Add in all the captions
  for (CandidateCollection::iterator it = candidates.begin();
       it != candidates.end();) {
    std::vector<CaptionCandidate> *captionOptions = it->second.get();
    if (captionOptions->size() <= 2) {
      if (verbose && captionOptions->size() == 2) {
        // This might be due to a continued Figure, but even if it is a mistake
        // we can hope the following steps will not find any figure regions
        // for the incorrect candidate we selected
        printf("Two candidates for %s%d, keeping both\n",
               getFigureTypeString(captionOptions->at(0).type),
               captionOptions->at(0).number);
      }
      for (CaptionCandidate cc : *captionOptions) {
        output[cc.page].push_back(
            CaptionStart(cc.page, cc.number, cc.word, cc.type));
      }
    } else if (verbose && captionOptions->size() > 0) {
      printf("%d candidates for %s%d, excluding them\n",
             (int)captionOptions->size(),
             getFigureTypeString(captionOptions->at(0).type),
             captionOptions->at(0).number);
    }
    candidates.erase(it++);
  }

  if (verbose)
    printf("Done parsing captions.\n\n");
  return output;
}