void TextFieldInputType::updatePlaceholderText()
{
    if (!supportsPlaceholder())
        return;
    HTMLElement* placeholder = element().placeholderElement();
    String placeholderText = element().strippedPlaceholder();
    if (placeholderText.isEmpty()) {
        if (placeholder)
            placeholder->remove(ASSERT_NO_EXCEPTION);
        return;
    }
    if (!placeholder) {
        RefPtrWillBeRawPtr<HTMLElement> newElement = HTMLDivElement::create(element().document());
        placeholder = newElement.get();
        placeholder->setShadowPseudoId(AtomicString("-webkit-input-placeholder", AtomicString::ConstructFromLiteral));
        placeholder->setAttribute(idAttr, ShadowElementNames::placeholder());
        Element* container = containerElement();
        Node* previous = container ? container : element().innerEditorElement();
        previous->parentNode()->insertBefore(placeholder, previous->nextSibling());
        ASSERT_WITH_SECURITY_IMPLICATION(placeholder->parentNode() == previous->parentNode());
    }
    placeholder->setTextContent(placeholderText);
}
Exemple #2
0
void FormAssociatedElement::insertedIntoTree()
{
    HTMLElement* element = toHTMLElement(this);
    if (element->fastHasAttribute(formAttr)) {
        element->document()->registerFormElementWithFormAttribute(this);
        Element* formElement = element->document()->getElementById(element->fastGetAttribute(formAttr));
        if (formElement && formElement->hasTagName(formTag)) {
            if (m_form)
                m_form->removeFormElement(this);
            m_form = static_cast<HTMLFormElement*>(formElement);
            m_form->registerFormElement(this);
        }
    }
    if (!m_form) {
        // This handles the case of a new form element being created by
        // JavaScript and inserted inside a form.  In the case of the parser
        // setting a form, we will already have a non-null value for m_form,
        // and so we don't need to do anything.
        m_form = element->findFormAncestor();
        if (m_form)
            m_form->registerFormElement(this);
    }
}
Exemple #3
0
JSValue JSHTMLElement::itemValue(ExecState* exec) const
{
    HTMLElement* element = impl();
    return toJS(exec, globalObject(), WTF::getPtr(element->itemValue()));
}
Exemple #4
0
bool HTMLDocument::isFrameSet() const
{
    HTMLElement* bodyElement = body();
    return bodyElement && bodyElement->renderer() && bodyElement->hasTagName(framesetTag);
}
JSC::JSValue documentEventHandlerAttribute(HTMLElement& element, const AtomicString& eventType)
{
    auto& document = element.document();
    return eventHandlerAttribute(document.getAttributeEventListener(eventType), document);
}
void HTMLSelectElement::add( const HTMLElement &element, const HTMLElement &before )
{
    if(impl) static_cast<HTMLSelectElementImpl*>(impl)->add(
            static_cast<HTMLElementImpl *>(element.handle()), static_cast<HTMLElementImpl *>(before.handle()) );
}
static inline bool nameShouldBeVisibleInDocumentAll(const HTMLElement& element)
{
    // http://www.whatwg.org/specs/web-apps/current-work/multipage/common-dom-interfaces.html#dom-htmlallcollection-nameditem:
    // The document.all collection returns only certain types of elements by name,
    // although it returns any type of element by id.
    return element.hasLocalName(aTag)
        || element.hasLocalName(appletTag)
        || element.hasLocalName(areaTag)
        || element.hasLocalName(embedTag)
        || element.hasLocalName(formTag)
        || element.hasLocalName(frameTag)
        || element.hasLocalName(framesetTag)
        || element.hasLocalName(iframeTag)
        || element.hasLocalName(imgTag)
        || element.hasLocalName(inputTag)
        || element.hasLocalName(objectTag)
        || element.hasLocalName(selectTag);
}
void FormAssociatedElement::insertedIntoDocument()
{
    HTMLElement* element = toHTMLElement(this);
    if (element->fastHasAttribute(formAttr))
        element->document()->registerFormElementWithFormAttribute(this);
}
HTMLBodyElement* HTMLDocument::htmlBodyElement() const
{
    HTMLElement* body = this->body();
    return (body && body->hasTagName(bodyTag)) ? toHTMLBodyElement(body) : 0;
}
Exemple #10
0
void setJSHTMLElementClassName(ExecState* exec, JSObject* thisObject, JSValue value)
{
    JSHTMLElement* castedThis = static_cast<JSHTMLElement*>(thisObject);
    HTMLElement* imp = static_cast<HTMLElement*>(castedThis->impl());
    imp->setAttribute(WebCore::HTMLNames::classAttr, valueToStringWithNullCheck(exec, value));
}
void RenderPartObject::updateWidget(bool onlyCreateNonNetscapePlugins)
{
  String url;
  String serviceType;
  Vector<String> paramNames;
  Vector<String> paramValues;
  Frame* frame = m_view->frame();
  
  if (element()->hasTagName(objectTag)) {

      HTMLObjectElement* o = static_cast<HTMLObjectElement*>(element());

      o->setNeedWidgetUpdate(false);
      if (!o->isFinishedParsingChildren())
        return;
      // Check for a child EMBED tag.
      HTMLEmbedElement* embed = 0;
      for (Node* child = o->firstChild(); child;) {
          if (child->hasTagName(embedTag)) {
              embed = static_cast<HTMLEmbedElement*>(child);
              break;
          } else if (child->hasTagName(objectTag))
              child = child->nextSibling();         // Don't descend into nested OBJECT tags
          else
              child = child->traverseNextNode(o);   // Otherwise descend (EMBEDs may be inside COMMENT tags)
      }
      
      // Use the attributes from the EMBED tag instead of the OBJECT tag including WIDTH and HEIGHT.
      HTMLElement *embedOrObject;
      if (embed) {
          embedOrObject = (HTMLElement *)embed;
          url = embed->url();
          serviceType = embed->serviceType();
      } else
          embedOrObject = (HTMLElement *)o;
      
      // If there was no URL or type defined in EMBED, try the OBJECT tag.
      if (url.isEmpty())
          url = o->m_url;
      if (serviceType.isEmpty())
          serviceType = o->m_serviceType;
      
      HashSet<StringImpl*, CaseFoldingHash> uniqueParamNames;
      
      // Scan the PARAM children.
      // Get the URL and type from the params if we don't already have them.
      // Get the attributes from the params if there is no EMBED tag.
      Node *child = o->firstChild();
      while (child && (url.isEmpty() || serviceType.isEmpty() || !embed)) {
          if (child->hasTagName(paramTag)) {
              HTMLParamElement* p = static_cast<HTMLParamElement*>(child);
              String name = p->name().lower();
              if (url.isEmpty() && (name == "src" || name == "movie" || name == "code" || name == "url"))
                  url = p->value();
              if (serviceType.isEmpty() && name == "type") {
                  serviceType = p->value();
                  int pos = serviceType.find(";");
                  if (pos != -1)
                      serviceType = serviceType.left(pos);
              }
              if (!embed && !name.isEmpty()) {
                  uniqueParamNames.add(p->name().impl());
                  paramNames.append(p->name());
                  paramValues.append(p->value());
              }
          }
          child = child->nextSibling();
      }
      
      // When OBJECT is used for an applet via Sun's Java plugin, the CODEBASE attribute in the tag
      // points to the Java plugin itself (an ActiveX component) while the actual applet CODEBASE is
      // in a PARAM tag. See <http://java.sun.com/products/plugin/1.2/docs/tags.html>. This means
      // we have to explicitly suppress the tag's CODEBASE attribute if there is none in a PARAM,
      // else our Java plugin will misinterpret it. [4004531]
      String codebase;
      if (!embed && MIMETypeRegistry::isJavaAppletMIMEType(serviceType)) {
          codebase = "codebase";
          uniqueParamNames.add(codebase.impl()); // pretend we found it in a PARAM already
      }
      
      // Turn the attributes of either the EMBED tag or OBJECT tag into arrays, but don't override PARAM values.
      NamedAttrMap* attributes = embedOrObject->attributes();
      if (attributes) {
          for (unsigned i = 0; i < attributes->length(); ++i) {
              Attribute* it = attributes->attributeItem(i);
              const AtomicString& name = it->name().localName();
              if (embed || !uniqueParamNames.contains(name.impl())) {
                  paramNames.append(name.string());
                  paramValues.append(it->value().string());
              }
          }
      }
      
      // If we still don't have a type, try to map from a specific CLASSID to a type.
      if (serviceType.isEmpty() && !o->m_classId.isEmpty())
          mapClassIdToServiceType(o->m_classId, serviceType);
      
      if (!isURLAllowed(document(), url))
          return;

      // Find out if we support fallback content.
      m_hasFallbackContent = false;
      for (Node *child = o->firstChild(); child && !m_hasFallbackContent; child = child->nextSibling()) {
          if ((!child->isTextNode() && !child->hasTagName(embedTag) && !child->hasTagName(paramTag)) || // Discount <embed> and <param>
              (child->isTextNode() && !static_cast<Text*>(child)->containsOnlyWhitespace()))
              m_hasFallbackContent = true;
      }
      
      if (onlyCreateNonNetscapePlugins) {
          KURL completedURL;
          if (!url.isEmpty())
              completedURL = frame->loader()->completeURL(url);
        
          if (frame->loader()->client()->objectContentType(completedURL, serviceType) == ObjectContentNetscapePlugin)
              return;
      }
      
      bool success = frame->loader()->requestObject(this, url, AtomicString(o->name()), serviceType, paramNames, paramValues);
      if (!success && m_hasFallbackContent)
          o->renderFallbackContent();
  } else if (element()->hasTagName(embedTag)) {
      HTMLEmbedElement *o = static_cast<HTMLEmbedElement*>(element());
      o->setNeedWidgetUpdate(false);
      url = o->url();
      serviceType = o->serviceType();

      if (url.isEmpty() && serviceType.isEmpty())
          return;
      if (!isURLAllowed(document(), url))
          return;
      
      // add all attributes set on the embed object
      NamedAttrMap* a = o->attributes();
      if (a) {
          for (unsigned i = 0; i < a->length(); ++i) {
              Attribute* it = a->attributeItem(i);
              paramNames.append(it->name().localName().string());
              paramValues.append(it->value().string());
          }
      }
      
      if (onlyCreateNonNetscapePlugins) {
          KURL completedURL;
          if (!url.isEmpty())
              completedURL = frame->loader()->completeURL(url);
          
          if (frame->loader()->client()->objectContentType(completedURL, serviceType) == ObjectContentNetscapePlugin)
              return;
          
      }
      
      frame->loader()->requestObject(this, url, o->getAttribute(nameAttr), serviceType, paramNames, paramValues);
  }
}
static inline bool isPluginElement(HTMLElement& element)
{
    return element.hasTagName(objectTag) || element.hasTagName(embedTag) || element.hasTagName(appletTag);
}
Exemple #13
0
PassRefPtr<FormSubmission> FormSubmission::create(HTMLFormElement* form, const Attributes& attributes, PassRefPtr<Event> event, bool lockHistory, FormSubmissionTrigger trigger)
{
    ASSERT(form);

    HTMLFormControlElement* submitButton = 0;
    if (event && event->target()) {
        for (Node* node = event->target()->toNode(); node; node = node->parentNode()) {
            if (node->isElementNode() && toElement(node)->isFormControlElement()) {
                submitButton = static_cast<HTMLFormControlElement*>(node);
                break;
            }
        }
    }

    FormSubmission::Attributes copiedAttributes;
    copiedAttributes.copyFrom(attributes);
    if (submitButton) {
        String attributeValue;
        if (!(attributeValue = submitButton->getAttribute(formactionAttr)).isNull())
            copiedAttributes.parseAction(attributeValue);
        if (!(attributeValue = submitButton->getAttribute(formenctypeAttr)).isNull())
            copiedAttributes.updateEncodingType(attributeValue);
        if (!(attributeValue = submitButton->getAttribute(formmethodAttr)).isNull())
            copiedAttributes.updateMethodType(attributeValue);
        if (!(attributeValue = submitButton->getAttribute(formtargetAttr)).isNull())
            copiedAttributes.setTarget(attributeValue);
    }
    
    Document* document = form->document();
    KURL actionURL = document->completeURL(copiedAttributes.action().isEmpty() ? document->url().string() : copiedAttributes.action());
    bool isMailtoForm = actionURL.protocolIs("mailto");
    bool isMultiPartForm = false;
    String encodingType = copiedAttributes.encodingType();

    if (copiedAttributes.method() == PostMethod) {
        isMultiPartForm = copiedAttributes.isMultiPartForm();
        if (isMultiPartForm && isMailtoForm) {
            encodingType = "application/x-www-form-urlencoded";
            isMultiPartForm = false;
        }
    }

    TextEncoding dataEncoding = isMailtoForm ? UTF8Encoding() : FormDataBuilder::encodingFromAcceptCharset(copiedAttributes.acceptCharset(), document);
    RefPtr<DOMFormData> domFormData = DOMFormData::create(dataEncoding.encodingForFormSubmission());
    Vector<pair<String, String> > formValues;

    bool containsPasswordData = false;
    for (unsigned i = 0; i < form->associatedElements().size(); ++i) {
        FormAssociatedElement* control = form->associatedElements()[i];
        HTMLElement* element = toHTMLElement(control);
        if (!element->isDisabledFormControl())
            control->appendFormData(*domFormData, isMultiPartForm);
        if (element->hasLocalName(inputTag)) {
            HTMLInputElement* input = static_cast<HTMLInputElement*>(control);
            if (input->isTextField()) {
                formValues.append(pair<String, String>(input->name().string(), input->value()));
                input->addSearchResult();
            }
            if (input->isPasswordField() && !input->value().isEmpty())
                containsPasswordData = true;
        }
    }

    RefPtr<FormData> formData;
    String boundary;

    if (isMultiPartForm) {
        formData = FormData::createMultiPart(*(static_cast<FormDataList*>(domFormData.get())), domFormData->encoding(), document);
        boundary = formData->boundary().data();
    } else {
        formData = FormData::create(*(static_cast<FormDataList*>(domFormData.get())), domFormData->encoding(), attributes.method() == GetMethod ? FormData::FormURLEncoded : FormData::parseEncodingType(encodingType));
        if (copiedAttributes.method() == PostMethod && isMailtoForm) {
            // Convert the form data into a string that we put into the URL.
            appendMailtoPostFormDataToURL(actionURL, *formData, encodingType);
            formData = FormData::create();
        }
    }

    formData->setIdentifier(generateFormDataIdentifier());
    formData->setContainsPasswordData(containsPasswordData);
    String targetOrBaseTarget = copiedAttributes.target().isEmpty() ? document->baseTarget() : copiedAttributes.target();
    RefPtr<FormState> formState = FormState::create(form, formValues, document, trigger);
    return adoptRef(new FormSubmission(copiedAttributes.method(), actionURL, targetOrBaseTarget, encodingType, formState.release(), formData.release(), boundary, lockHistory, event));
}
void InsertListCommand::doApply()
{
    if (endingSelection().isNone())
        return;
    
    if (!endingSelection().rootEditableElement())
        return;
    
    VisiblePosition visibleEnd = endingSelection().visibleEnd();
    VisiblePosition visibleStart = endingSelection().visibleStart();
    // When a selection ends at the start of a paragraph, we rarely paint 
    // the selection gap before that paragraph, because there often is no gap.  
    // In a case like this, it's not obvious to the user that the selection 
    // ends "inside" that paragraph, so it would be confusing if InsertUn{Ordered}List 
    // operated on that paragraph.
    // FIXME: We paint the gap before some paragraphs that are indented with left 
    // margin/padding, but not others.  We should make the gap painting more consistent and 
    // then use a left margin/padding rule here.
    if (visibleEnd != visibleStart && isStartOfParagraph(visibleEnd))
        setEndingSelection(VisibleSelection(visibleStart, visibleEnd.previous(true)));

    if (endingSelection().isRange() && modifyRange())
        return;
    
    // FIXME: This will produce unexpected results for a selection that starts just before a
    // table and ends inside the first cell, selectionForParagraphIteration should probably
    // be renamed and deployed inside setEndingSelection().
    Node* selectionNode = endingSelection().start().node();
    const QualifiedName listTag = (m_type == OrderedList) ? olTag : ulTag;
    Node* listChildNode = enclosingListChild(selectionNode);
    bool switchListType = false;
    if (listChildNode) {
        // Remove the list chlild.
        HTMLElement* listNode = enclosingList(listChildNode);
        if (!listNode)
            listNode = fixOrphanedListChild(listChildNode);
        if (!listNode->hasTagName(listTag))
            // listChildNode will be removed from the list and a list of type m_type will be created.
            switchListType = true;
        Node* nextListChild;
        Node* previousListChild;
        VisiblePosition start;
        VisiblePosition end;
        if (listChildNode->hasTagName(liTag)) {
            start = firstDeepEditingPositionForNode(listChildNode);
            end = lastDeepEditingPositionForNode(listChildNode);
            nextListChild = listChildNode->nextSibling();
            previousListChild = listChildNode->previousSibling();
        } else {
            // A paragraph is visually a list item minus a list marker.  The paragraph will be moved.
            start = startOfParagraph(endingSelection().visibleStart());
            end = endOfParagraph(endingSelection().visibleEnd());
            nextListChild = enclosingListChild(end.next().deepEquivalent().node());
            ASSERT(nextListChild != listChildNode);
            if (enclosingList(nextListChild) != listNode)
                nextListChild = 0;
            previousListChild = enclosingListChild(start.previous().deepEquivalent().node());
            ASSERT(previousListChild != listChildNode);
            if (enclosingList(previousListChild) != listNode)
                previousListChild = 0;
        }
        // When removing a list, we must always create a placeholder to act as a point of insertion
        // for the list content being removed.
        RefPtr<Element> placeholder = createBreakElement(document());
        RefPtr<Element> nodeToInsert = placeholder;
        // If the content of the list item will be moved into another list, put it in a list item
        // so that we don't create an orphaned list child.
        if (enclosingList(listNode)) {
            nodeToInsert = createListItemElement(document());
            appendNode(placeholder, nodeToInsert);
        }
        
        if (nextListChild && previousListChild) {
            // We want to pull listChildNode out of listNode, and place it before nextListChild 
            // and after previousListChild, so we split listNode and insert it between the two lists.  
            // But to split listNode, we must first split ancestors of listChildNode between it and listNode,
            // if any exist.
            // FIXME: We appear to split at nextListChild as opposed to listChildNode so that when we remove
            // listChildNode below in moveParagraphs, previousListChild will be removed along with it if it is 
            // unrendered. But we ought to remove nextListChild too, if it is unrendered.
            splitElement(listNode, splitTreeToNode(nextListChild, listNode));
            insertNodeBefore(nodeToInsert, listNode);
        } else if (nextListChild || listChildNode->parentNode() != listNode) {
            // Just because listChildNode has no previousListChild doesn't mean there isn't any content
            // in listNode that comes before listChildNode, as listChildNode could have ancestors
            // between it and listNode. So, we split up to listNode before inserting the placeholder
            // where we're about to move listChildNode to.
            if (listChildNode->parentNode() != listNode)
                splitElement(listNode, splitTreeToNode(listChildNode, listNode).get());
            insertNodeBefore(nodeToInsert, listNode);
        } else
            insertNodeAfter(nodeToInsert, listNode);
        
        VisiblePosition insertionPoint = VisiblePosition(Position(placeholder.get(), 0));
        moveParagraphs(start, end, insertionPoint, true);
    }
    if (!listChildNode || switchListType || m_forceCreateList) {
        // Create list.
        VisiblePosition originalStart = endingSelection().visibleStart();
        VisiblePosition start = startOfParagraph(originalStart);
        VisiblePosition end = endOfParagraph(endingSelection().visibleEnd());
        
        // Check for adjoining lists.
        VisiblePosition previousPosition = start.previous(true);
        VisiblePosition nextPosition = end.next(true);
        RefPtr<HTMLElement> listItemElement = createListItemElement(document());
        RefPtr<HTMLElement> placeholder = createBreakElement(document());
        appendNode(placeholder, listItemElement);
        Element* previousList = outermostEnclosingList(previousPosition.deepEquivalent().node());
        Element* nextList = outermostEnclosingList(nextPosition.deepEquivalent().node());
        Node* startNode = start.deepEquivalent().node();
        Node* previousCell = enclosingTableCell(previousPosition.deepEquivalent());
        Node* nextCell = enclosingTableCell(nextPosition.deepEquivalent());
        Node* currentCell = enclosingTableCell(start.deepEquivalent());
        if (previousList && (!previousList->hasTagName(listTag) || startNode->isDescendantOf(previousList) || previousCell != currentCell))
            previousList = 0;
        if (nextList && (!nextList->hasTagName(listTag) || startNode->isDescendantOf(nextList) || nextCell != currentCell))
            nextList = 0;
        // Place list item into adjoining lists.
        if (previousList)
            appendNode(listItemElement, previousList);
        else if (nextList)
            insertNodeAt(listItemElement, Position(nextList, 0));
        else {
            // Create the list.
            RefPtr<HTMLElement> listElement = m_type == OrderedList ? createOrderedListElement(document()) : createUnorderedListElement(document());
            m_listElement = listElement;
            appendNode(listItemElement, listElement);
            
            if (start == end && isBlock(start.deepEquivalent().node())) {
                // Inserting the list into an empty paragraph that isn't held open 
                // by a br or a '\n', will invalidate start and end.  Insert 
                // a placeholder and then recompute start and end.
                RefPtr<Node> placeholder = insertBlockPlaceholder(start.deepEquivalent());
                start = VisiblePosition(Position(placeholder.get(), 0));
                end = start;
            }
            
            // Insert the list at a position visually equivalent to start of the
            // paragraph that is being moved into the list. 
            // Try to avoid inserting it somewhere where it will be surrounded by 
            // inline ancestors of start, since it is easier for editing to produce 
            // clean markup when inline elements are pushed down as far as possible.
            Position insertionPos(start.deepEquivalent().upstream());
            // Also avoid the containing list item.
            Node* listChild = enclosingListChild(insertionPos.node());
            if (listChild && listChild->hasTagName(liTag))
                insertionPos = positionInParentBeforeNode(listChild);

            insertNodeAt(listElement, insertionPos);

            // We inserted the list at the start of the content we're about to move
            // Update the start of content, so we don't try to move the list into itself.  bug 19066
            if (insertionPos == start.deepEquivalent())
                start = startOfParagraph(originalStart);
        }
        moveParagraph(start, end, VisiblePosition(Position(placeholder.get(), 0)), true);
        if (nextList && previousList)
            mergeIdenticalElements(previousList, nextList);
    }
}
void HTMLDocument::setBody(const HTMLElement &_body)
{
    if (!impl) return;
    ((HTMLDocumentImpl *)impl)->setBody(static_cast<HTMLElementImpl *>(_body.handle()));
    return;
}
void FormAssociatedElement::didMoveToNewDocument(Document* oldDocument)
{
    HTMLElement* element = toHTMLElement(this);
    if (oldDocument && element->fastHasAttribute(formAttr))
        oldDocument->unregisterFormElementWithFormAttribute(this);
}
Exemple #17
0
v8::Handle<v8::Value> V8HTMLElement::itemValueAccessorGetter(v8::Local<v8::String> name, const v8::AccessorInfo& info)
{
    HTMLElement* impl = V8HTMLElement::toNative(info.Holder());
    return toV8Object(impl->itemValue().get());
}
Exemple #18
0
void setJSHTMLElementTabIndex(ExecState* exec, JSObject* thisObject, JSValue value)
{
    JSHTMLElement* castedThis = static_cast<JSHTMLElement*>(thisObject);
    HTMLElement* imp = static_cast<HTMLElement*>(castedThis->impl());
    imp->setTabIndex(value.toInt32(exec));
}
void FormAssociatedElement::willMoveToNewOwnerDocument()
{
    HTMLElement* element = toHTMLElement(this);
    if (element->fastHasAttribute(formAttr))
        element->document()->unregisterFormElementWithFormAttribute(this);
}
Exemple #20
0
void setJSHTMLElementHidden(ExecState* exec, JSObject* thisObject, JSValue value)
{
    JSHTMLElement* castedThis = static_cast<JSHTMLElement*>(thisObject);
    HTMLElement* imp = static_cast<HTMLElement*>(castedThis->impl());
    imp->setBooleanAttribute(WebCore::HTMLNames::hiddenAttr, value.toBoolean(exec));
}
void FormAssociatedElement::removedFromDocument()
{
    HTMLElement* element = toHTMLElement(this);
    if (element->fastHasAttribute(formAttr))
        element->document()->unregisterFormElementWithFormAttribute(this);
}
Exemple #22
0
/*
|-------------------|	  |----------------|	       |------------------------------|
| string passing in | --> | is it tainted? | --> Y --> | taint the element / document | (bad approach, need to reset the document taint)
|___________________|	  |________________|	       |______________________________| 
					   |
					   |	       |-------------------|
					   | --> Y --> | taint the element | (best approach)
						       |-------------------|
the ideal implementation is to set the element as tainted only (no need to set the doucment as tainted), and then the js can detect the element is tainted or not.
however, i found that js level detection does not work for the element now, so i tainted the document for reporting.
this method has the side effect, if the element is untatined, then we need to clear the tainted flag of the document.
*/
void setJSHTMLElementInnerHTML(ExecState* exec, JSObject* thisObject, JSValue value)
{
#if defined(JSC_TAINTED)
    unsigned int tainted = TaintedUtils::isTainted(exec, value);
#endif
    JSHTMLElement* castedThis = static_cast<JSHTMLElement*>(thisObject);
    HTMLElement* imp = static_cast<HTMLElement*>(castedThis->impl());
    ExceptionCode ec = 0;
    imp->setInnerHTML(valueToStringWithNullCheck(exec, value), ec);
    setDOMException(exec, ec);
#if defined(JSC_TAINTED)
    unsigned int imp_tainted = imp->tainted();

    if (tainted) {
// cerr 
/*
	char cid[50];
	JSValue id = jsString(exec, imp->getAttribute(WebCore::HTMLNames::idAttr));
	UString sid = id.toString(exec);
	snprintf(cid, 50, "%s", sid.utf8(true).data());
	cerr << "setJSHTMLElementInnerHTML:SETTING:" << cid << ":" << tainted << ":" << imp_tainted << endl;
*/
// cerr

	//
	// i dont know why this tainted flag cannot be queried from js level
	// seems like the HTML element is persistent, but it is not the right HTML element, so need to loop through and find out
	//
    	imp->setTainted(tainted);
	imp->document()->setTainted(tainted);

	TaintedStructure trace_struct;
	trace_struct.taintedno = tainted;
	trace_struct.internalfunc = "setJSHTMLElementInnerHTML";
	trace_struct.jsfunc = "HTMLElement.innerHTML";
	trace_struct.action = "sink";
	trace_struct.value = TaintedUtils::UString2string(value.toString(exec));

	TaintedTrace* trace = TaintedTrace::getInstance();
	trace->addTaintedTrace(trace_struct);

    // 
    // this condition really difficult to understand. 
    // wanna to reset the innerHTML of this element if it is tainted and passing in string is not tainted.
    // there is a problem in this code, it is silly to do it, as if the imp->setTainted() is supposed to be work, then there is no need to do in this way.
    //
    } else if (imp_tainted == imp->document()->tainted() 
	&& imp_tainted != 0
	&& !tainted) {

// cerr
/*
	char cid[50];
	JSValue id = jsString(exec, imp->getAttribute(WebCore::HTMLNames::idAttr));
	UString sid = id.toString(exec);
	snprintf(cid, 50, "%s", sid.utf8(true).data());
	cerr << "setJSHTMLElementInnerHTML:RESETTING:" << cid << endl;
*/
// cerr

	TaintedStructure trace_struct;
	trace_struct.taintedno = 0;
	// trace_struct.taintedno = imp_tainted;
	trace_struct.internalfunc = "setJSHTMLElementInnerHTML";
	trace_struct.jsfunc = "HTMLElement.innerHTML";
	trace_struct.action = "reset";
	trace_struct.value = TaintedUtils::UString2string(value.toString(exec));

	TaintedTrace* trace = TaintedTrace::getInstance();
	trace->addTaintedTrace(trace_struct);

    	imp->setTainted(0);
    }
#endif
}
Exemple #23
0
bool HTMLCollection::checkForNameMatch(Element* element, bool checkName, const AtomicString& name) const
{
    if (!element->isHTMLElement())
        return false;
    
    HTMLElement* e = toHTMLElement(element);
    if (!checkName)
        return e->getIdAttribute() == name;

    // document.all returns only images, forms, applets, objects and embeds
    // by name (though everything by id)
    if (m_type == DocAll && 
        !(e->hasLocalName(imgTag) || e->hasLocalName(formTag) ||
          e->hasLocalName(appletTag) || e->hasLocalName(objectTag) ||
          e->hasLocalName(embedTag) || e->hasLocalName(inputTag) ||
          e->hasLocalName(selectTag)))
        return false;

    return e->getAttribute(nameAttr) == name && e->getIdAttribute() != name;
}
Exemple #24
0
void setJSHTMLElementSpellcheck(ExecState* exec, JSObject* thisObject, JSValue value)
{
    JSHTMLElement* castedThis = static_cast<JSHTMLElement*>(thisObject);
    HTMLElement* imp = static_cast<HTMLElement*>(castedThis->impl());
    imp->setSpellcheck(value.toBoolean(exec));
}
void setWindowEventHandlerAttribute(JSC::ExecState& state, JSC::JSObject& wrapper, HTMLElement& element, const AtomicString& eventType, JSC::JSValue value)
{
    ASSERT(wrapper.globalObject());
    element.document().setWindowAttributeEventListener(eventType, createEventListenerForEventHandlerAttribute(state, value, *wrapper.globalObject()));
}
Exemple #26
0
RenderStyle* RenderTextControlSingleLine::textBaseStyle() const
{
    HTMLElement* innerBlock = innerBlockElement();
    return innerBlock ? innerBlock->renderer()->style() : style();
}
Exemple #27
0
void HTMLDocument::setDir(const String& value)
{
    HTMLElement* b = body();
    if (b)
        b->setAttribute(dirAttr, value);
}
Exemple #28
0
void RenderTextControlSingleLine::layout()
{
    // FIXME: We should remove the height-related hacks in layout() and
    // styleDidChange(). We need them because
    // - Center the inner elements vertically if the input height is taller than
    //   the intrinsic height of the inner elements.
    // - Shrink the inner elment heights if the input height is samller than the
    //   intrinsic heights of the inner elements.

    // We don't honor paddings and borders for textfields without decorations
    // and type=search if the text height is taller than the contentHeight()
    // because of compability.

    LayoutUnit oldHeight = height();
    computeLogicalHeight();

    LayoutUnit oldWidth = width();
    computeLogicalWidth();

    bool relayoutChildren = oldHeight != height() || oldWidth != width();

    RenderBox* innerTextRenderer = innerTextElement()->renderBox();
    ASSERT(innerTextRenderer);
    RenderBox* innerBlockRenderer = innerBlockElement() ? innerBlockElement()->renderBox() : 0;
    HTMLElement* container = containerElement();
    RenderBox* containerRenderer = container ? container->renderBox() : 0;

    // Set the text block height
    LayoutUnit desiredHeight = textBlockHeight();
    LayoutUnit currentHeight = innerTextRenderer->height();

    LayoutUnit heightLimit = (inputElement()->isSearchField() || !container) ? height() : contentHeight();
    if (currentHeight > heightLimit) {
        if (desiredHeight != currentHeight)
            relayoutChildren = true;
        innerTextRenderer->style()->setHeight(Length(desiredHeight, Fixed));
        m_desiredInnerTextHeight = desiredHeight;
        if (innerBlockRenderer)
            innerBlockRenderer->style()->setHeight(Length(desiredHeight, Fixed));
    }
    // The container might be taller because of decoration elements.
    if (containerRenderer) {
        containerRenderer->layoutIfNeeded();
        LayoutUnit containerHeight = containerRenderer->height();
        if (containerHeight > heightLimit) {
            containerRenderer->style()->setHeight(Length(heightLimit, Fixed));
            relayoutChildren = true;
        } else if (containerRenderer->height() < contentHeight()) {
            containerRenderer->style()->setHeight(Length(contentHeight(), Fixed));
            relayoutChildren = true;
        } else
            containerRenderer->style()->setHeight(Length(containerHeight, Fixed));
    }

    RenderBlock::layoutBlock(relayoutChildren);

    // Center the child block vertically
    currentHeight = innerTextRenderer->height();
    if (!container && currentHeight != contentHeight()) {
        LayoutUnit heightDiff = currentHeight - contentHeight();
        innerTextRenderer->setY(innerTextRenderer->y() - (heightDiff / 2 + layoutMod(heightDiff, 2)));
    } else if (inputElement()->isSearchField() && containerRenderer && containerRenderer->height() > contentHeight()) {
        // A quirk for find-in-page box on Safari Windows.
        // http://webkit.org/b/63157
        LayoutUnit heightDiff = containerRenderer->height() - contentHeight();
        containerRenderer->setY(containerRenderer->y() - (heightDiff / 2 + layoutMod(heightDiff, 2)));
    }

    // Ignores the paddings for the inner spin button.
    if (RenderBox* innerSpinBox = innerSpinButtonElement() ? innerSpinButtonElement()->renderBox() : 0) {
        RenderBox* parentBox = innerSpinBox->parentBox();
        if (containerRenderer && !containerRenderer->style()->isLeftToRightDirection())
            innerSpinBox->setLocation(LayoutPoint(-paddingLeft(), -paddingTop()));
        else
            innerSpinBox->setLocation(LayoutPoint(parentBox->width() - innerSpinBox->width() + paddingRight(), -paddingTop()));
        innerSpinBox->setHeight(height() - borderTop() - borderBottom());
    }

    HTMLElement* placeholderElement = inputElement()->placeholderElement();
    if (RenderBox* placeholderBox = placeholderElement ? placeholderElement->renderBox() : 0) {
        placeholderBox->style()->setWidth(Length(innerTextRenderer->width() - placeholderBox->borderAndPaddingWidth(), Fixed));
        placeholderBox->style()->setHeight(Length(innerTextRenderer->height() - placeholderBox->borderAndPaddingHeight(), Fixed));
        placeholderBox->layoutIfNeeded();
        LayoutPoint textOffset = innerTextRenderer->location();
        if (innerBlockElement() && innerBlockElement()->renderBox())
            textOffset += toLayoutSize(innerBlockElement()->renderBox()->location());
        if (containerRenderer)
            textOffset += toLayoutSize(containerRenderer->location());
        placeholderBox->setLocation(textOffset);
    }
}
void RenderTextControlSingleLine::layout()
{
    StackStats::LayoutCheckPoint layoutCheckPoint;

    // FIXME: We should remove the height-related hacks in layout() and
    // styleDidChange(). We need them because
    // - Center the inner elements vertically if the input height is taller than
    //   the intrinsic height of the inner elements.
    // - Shrink the inner elment heights if the input height is samller than the
    //   intrinsic heights of the inner elements.

    // We don't honor paddings and borders for textfields without decorations
    // and type=search if the text height is taller than the contentHeight()
    // because of compability.

    RenderTextControlInnerBlock* innerTextRenderer = innerTextElement()->renderer();
    RenderBox* innerBlockRenderer = innerBlockElement() ? innerBlockElement()->renderBox() : 0;

    // To ensure consistency between layouts, we need to reset any conditionally overriden height.
    if (innerTextRenderer && !innerTextRenderer->style().logicalHeight().isAuto()) {
        innerTextRenderer->style().setLogicalHeight(Length(Auto));
        setNeedsLayoutOnAncestors(innerTextRenderer, this);
    }
    if (innerBlockRenderer && !innerBlockRenderer->style().logicalHeight().isAuto()) {
        innerBlockRenderer->style().setLogicalHeight(Length(Auto));
        setNeedsLayoutOnAncestors(innerBlockRenderer, this);
    }

    RenderBlockFlow::layoutBlock(false);

    HTMLElement* container = containerElement();
    RenderBox* containerRenderer = container ? container->renderBox() : 0;

    // Set the text block height
    LayoutUnit desiredLogicalHeight = textBlockLogicalHeight();
    LayoutUnit logicalHeightLimit = computeLogicalHeightLimit();
    if (innerTextRenderer && innerTextRenderer->logicalHeight() > logicalHeightLimit) {
        if (desiredLogicalHeight != innerTextRenderer->logicalHeight())
            setNeedsLayout(MarkOnlyThis);

        m_desiredInnerTextLogicalHeight = desiredLogicalHeight;

        innerTextRenderer->style().setLogicalHeight(Length(desiredLogicalHeight, Fixed));
        innerTextRenderer->setNeedsLayout(MarkOnlyThis);
        if (innerBlockRenderer) {
            innerBlockRenderer->style().setLogicalHeight(Length(desiredLogicalHeight, Fixed));
            innerBlockRenderer->setNeedsLayout(MarkOnlyThis);
        }
    }
    // The container might be taller because of decoration elements.
    if (containerRenderer) {
        containerRenderer->layoutIfNeeded();
        LayoutUnit containerLogicalHeight = containerRenderer->logicalHeight();
        if (containerLogicalHeight > logicalHeightLimit) {
            containerRenderer->style().setLogicalHeight(Length(logicalHeightLimit, Fixed));
            setNeedsLayout(MarkOnlyThis);
        } else if (containerRenderer->logicalHeight() < contentLogicalHeight()) {
            containerRenderer->style().setLogicalHeight(Length(contentLogicalHeight(), Fixed));
            setNeedsLayout(MarkOnlyThis);
        } else
            containerRenderer->style().setLogicalHeight(Length(containerLogicalHeight, Fixed));
    }

    // If we need another layout pass, we have changed one of children's height so we need to relayout them.
    if (needsLayout())
        RenderBlockFlow::layoutBlock(true);

    // Center the child block in the block progression direction (vertical centering for horizontal text fields).
    if (!container && innerTextRenderer && innerTextRenderer->height() != contentLogicalHeight())
        centerRenderer(*innerTextRenderer);
    else
        centerContainerIfNeeded(containerRenderer);

    // Ignores the paddings for the inner spin button.
    if (RenderBox* innerSpinBox = innerSpinButtonElement() ? innerSpinButtonElement()->renderBox() : 0) {
        RenderBox* parentBox = innerSpinBox->parentBox();
        if (containerRenderer && !containerRenderer->style().isLeftToRightDirection())
            innerSpinBox->setLogicalLocation(LayoutPoint(-paddingLogicalLeft(), -paddingBefore()));
        else
            innerSpinBox->setLogicalLocation(LayoutPoint(parentBox->logicalWidth() - innerSpinBox->logicalWidth() + paddingLogicalRight(), -paddingBefore()));
        innerSpinBox->setLogicalHeight(logicalHeight() - borderBefore() - borderAfter());
    }

    HTMLElement* placeholderElement = inputElement().placeholderElement();
    if (RenderBox* placeholderBox = placeholderElement ? placeholderElement->renderBox() : 0) {
        LayoutSize innerTextSize;
        if (innerTextRenderer)
            innerTextSize = innerTextRenderer->size();
        placeholderBox->style().setWidth(Length(innerTextSize.width() - placeholderBox->horizontalBorderAndPaddingExtent(), Fixed));
        placeholderBox->style().setHeight(Length(innerTextSize.height() - placeholderBox->verticalBorderAndPaddingExtent(), Fixed));
        bool neededLayout = placeholderBox->needsLayout();
        bool placeholderBoxHadLayout = placeholderBox->everHadLayout();
        placeholderBox->layoutIfNeeded();
        LayoutPoint textOffset;
        if (innerTextRenderer)
            textOffset = innerTextRenderer->location();
        if (innerBlockElement() && innerBlockElement()->renderBox())
            textOffset += toLayoutSize(innerBlockElement()->renderBox()->location());
        if (containerRenderer)
            textOffset += toLayoutSize(containerRenderer->location());
        placeholderBox->setLocation(textOffset);

        if (!placeholderBoxHadLayout && placeholderBox->checkForRepaintDuringLayout()) {
            // This assumes a shadow tree without floats. If floats are added, the
            // logic should be shared with RenderBlock::layoutBlockChild.
            placeholderBox->repaint();
        }
        // The placeholder gets layout last, after the parent text control and its other children,
        // so in order to get the correct overflow from the placeholder we need to recompute it now.
        if (neededLayout)
            computeOverflow(clientLogicalBottom());
    }

#if PLATFORM(IOS)
    // FIXME: We should not be adjusting styles during layout. <rdar://problem/7675493>
    if (inputElement().isSearchField())
        RenderThemeIOS::adjustRoundBorderRadius(style(), *this);
#endif
}
Exemple #30
0
void LayoutTextControlSingleLine::layout() {
  LayoutAnalyzer::Scope analyzer(*this);

  LayoutBlockFlow::layoutBlock(true);

  LayoutBox* innerEditorLayoutObject = innerEditorElement()->layoutBox();
  Element* container = containerElement();
  LayoutBox* containerLayoutObject =
      container ? container->layoutBox() : nullptr;
  // Center the child block in the block progression direction (vertical
  // centering for horizontal text fields).
  if (!container && innerEditorLayoutObject &&
      innerEditorLayoutObject->size().height() != contentLogicalHeight()) {
    LayoutUnit logicalHeightDiff =
        innerEditorLayoutObject->logicalHeight() - contentLogicalHeight();
    innerEditorLayoutObject->setLogicalTop(
        innerEditorLayoutObject->logicalTop() -
        (logicalHeightDiff / 2 + layoutMod(logicalHeightDiff, 2)));
  } else if (container && containerLayoutObject &&
             containerLayoutObject->size().height() != contentLogicalHeight()) {
    LayoutUnit logicalHeightDiff =
        containerLayoutObject->logicalHeight() - contentLogicalHeight();
    containerLayoutObject->setLogicalTop(
        containerLayoutObject->logicalTop() -
        (logicalHeightDiff / 2 + layoutMod(logicalHeightDiff, 2)));
  }

  HTMLElement* placeholderElement = inputElement()->placeholderElement();
  if (LayoutBox* placeholderBox =
          placeholderElement ? placeholderElement->layoutBox() : 0) {
    LayoutSize innerEditorSize;

    if (innerEditorLayoutObject)
      innerEditorSize = innerEditorLayoutObject->size();
    placeholderBox->mutableStyleRef().setWidth(Length(
        innerEditorSize.width() - placeholderBox->borderAndPaddingWidth(),
        Fixed));
    bool neededLayout = placeholderBox->needsLayout();
    placeholderBox->layoutIfNeeded();
    LayoutPoint textOffset;
    if (innerEditorLayoutObject)
      textOffset = innerEditorLayoutObject->location();
    if (editingViewPortElement() && editingViewPortElement()->layoutBox())
      textOffset +=
          toLayoutSize(editingViewPortElement()->layoutBox()->location());
    if (containerLayoutObject)
      textOffset += toLayoutSize(containerLayoutObject->location());
    if (innerEditorLayoutObject) {
      // We use inlineBlockBaseline() for innerEditor because it has no
      // inline boxes when we show the placeholder.
      int innerEditorBaseline =
          innerEditorLayoutObject->inlineBlockBaseline(HorizontalLine);
      // We use firstLineBoxBaseline() for placeholder.
      // TODO(tkent): It's inconsistent with innerEditorBaseline. However
      // placeholderBox->inlineBlockBase() is unexpectedly larger.
      int placeholderBaseline = placeholderBox->firstLineBoxBaseline();
      textOffset += LayoutSize(0, innerEditorBaseline - placeholderBaseline);
    }
    placeholderBox->setLocation(textOffset);

    // The placeholder gets layout last, after the parent text control and its
    // other children, so in order to get the correct overflow from the
    // placeholder we need to recompute it now.
    if (neededLayout)
      computeOverflow(clientLogicalBottom());
  }
}