Add support for the translate attribute in html elements.
authorcommit-queue@webkit.org <commit-queue@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 16 Feb 2012 05:42:02 +0000 (05:42 +0000)
committercommit-queue@webkit.org <commit-queue@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 16 Feb 2012 05:42:02 +0000 (05:42 +0000)
https://bugs.webkit.org/show_bug.cgi?id=78751

Patch by Pablo Flouret <pablof@motorola.com> on 2012-02-15
Reviewed by Adam Barth.

The translate attribute is used to specify whether an element's
attribute values and the values of its Text node children are to be
translated when the page is localized, or whether to leave them
unchanged.

Details at http://www.whatwg.org/specs/web-apps/current-work/multipage/elements.html#attr-translate

Source/WebCore:

Test: fast/dom/HTMLElement/translate.html

* html/HTMLAttributeNames.in:
* html/HTMLElement.cpp:
(WebCore::HTMLElement::translateAttributeMode):
(WebCore):
(WebCore::HTMLElement::translate):
(WebCore::HTMLElement::setTranslate):
* html/HTMLElement.h:
(HTMLElement):
* html/HTMLElement.idl:

LayoutTests:

* fast/dom/HTMLElement/translate-expected.txt: Added.
* fast/dom/HTMLElement/translate.html: Added.

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@107883 268f45cc-cd09-0410-ab3c-d52691b4dbfc

LayoutTests/ChangeLog
LayoutTests/fast/dom/HTMLElement/translate-expected.txt [new file with mode: 0644]
LayoutTests/fast/dom/HTMLElement/translate.html [new file with mode: 0644]
Source/WebCore/ChangeLog
Source/WebCore/html/HTMLAttributeNames.in
Source/WebCore/html/HTMLElement.cpp
Source/WebCore/html/HTMLElement.h
Source/WebCore/html/HTMLElement.idl

index ac11b719780377fd941889fc0142aae1d9d5ac13..719e15c20f79cb520ef39c3497ecdab4552f1c10 100644 (file)
@@ -1,3 +1,20 @@
+2012-02-15  Pablo Flouret  <pablof@motorola.com>
+
+        Add support for the translate attribute in html elements.
+        https://bugs.webkit.org/show_bug.cgi?id=78751
+
+        Reviewed by Adam Barth.
+
+        The translate attribute is used to specify whether an element's
+        attribute values and the values of its Text node children are to be
+        translated when the page is localized, or whether to leave them
+        unchanged.
+
+        Details at http://www.whatwg.org/specs/web-apps/current-work/multipage/elements.html#attr-translate
+
+        * fast/dom/HTMLElement/translate-expected.txt: Added.
+        * fast/dom/HTMLElement/translate.html: Added.
+
 2012-02-15  Noel Gordon  <noel.gordon@gmail.com>
 
         Unreviewed. compositing/culling/scrolled-within-boxshadow.html IMAGE failure.
diff --git a/LayoutTests/fast/dom/HTMLElement/translate-expected.txt b/LayoutTests/fast/dom/HTMLElement/translate-expected.txt
new file mode 100644 (file)
index 0000000..3ee9e3d
--- /dev/null
@@ -0,0 +1,170 @@
+Test the translate attribute.
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+translate should be "yes" by default.
+PASS target.translate is true
+PASS target.getAttribute('translate') is null
+
+target.translate = false;
+PASS target.translate is false
+PASS target.getAttribute('translate') is "no"
+
+target.setAttribute("translate", "yes");
+PASS target.translate is true
+PASS target.getAttribute('translate') is "yes"
+
+target.setAttribute("translate", "no");
+PASS target.translate is false
+PASS target.getAttribute('translate') is "no"
+
+target.setAttribute("translate", "YES");
+PASS target.translate is true
+PASS target.getAttribute('translate') is "YES"
+
+target.setAttribute("translate", "NO");
+PASS target.translate is false
+PASS target.getAttribute('translate') is "NO"
+
+target.setAttribute("translate", "INVALID");
+PASS target.translate is true
+PASS target.getAttribute('translate') is "INVALID"
+
+Removing translate attribute.
+PASS target.getAttribute('translate') is null
+PASS target.translate is true
+
+Creating targetChild element as a child of target.
+PASS targetChild.translate is true
+PASS targetChild.getAttribute('translate') is null
+
+Setting target.translate = false. targetChild should inherit the translate value from its parents.
+PASS targetChild.translate is false
+PASS targetChild.getAttribute('translate') is null
+
+Setting targetChild.setAttribute('translate', 'INVALID'). Should inherit the translate value from its parents.
+PASS target.translate is false
+PASS target.getAttribute('translate') is "no"
+PASS targetChild.translate is false
+PASS targetChild.getAttribute('translate') is "INVALID"
+
+targetChild.translate = true;
+PASS targetChild.translate is true
+PASS targetChild.getAttribute('translate') is "yes"
+PASS target.translate is false
+PASS target.getAttribute('translate') is "no"
+
+
+PASS target.translate is initialExpectation
+PASS target.translate is lastExpectation
+PASS target.getAttribute('translate') is lastAttributeExpectation
+PASS target.translate is initialExpectation
+PASS target.translate is lastExpectation
+PASS target.getAttribute('translate') is lastAttributeExpectation
+PASS target.translate is initialExpectation
+PASS target.translate is lastExpectation
+PASS target.getAttribute('translate') is lastAttributeExpectation
+PASS target.translate is initialExpectation
+PASS target.translate is lastExpectation
+PASS target.getAttribute('translate') is lastAttributeExpectation
+PASS target.translate is initialExpectation
+PASS target.translate is lastExpectation
+PASS target.getAttribute('translate') is lastAttributeExpectation
+PASS target.translate is initialExpectation
+PASS target.translate is lastExpectation
+PASS target.getAttribute('translate') is lastAttributeExpectation
+PASS target.translate is initialExpectation
+PASS target.translate is lastExpectation
+PASS target.getAttribute('translate') is lastAttributeExpectation
+PASS target.translate is initialExpectation
+PASS target.translate is lastExpectation
+PASS target.getAttribute('translate') is lastAttributeExpectation
+PASS target.translate is initialExpectation
+PASS target.translate is lastExpectation
+PASS target.getAttribute('translate') is lastAttributeExpectation
+PASS target.translate is initialExpectation
+PASS target.translate is lastExpectation
+PASS target.getAttribute('translate') is lastAttributeExpectation
+PASS target.translate is initialExpectation
+PASS target.translate is lastExpectation
+PASS target.getAttribute('translate') is lastAttributeExpectation
+PASS target.translate is initialExpectation
+PASS target.translate is lastExpectation
+PASS target.getAttribute('translate') is lastAttributeExpectation
+PASS target.translate is initialExpectation
+PASS target.translate is lastExpectation
+PASS target.getAttribute('translate') is lastAttributeExpectation
+PASS target.translate is initialExpectation
+PASS target.translate is lastExpectation
+PASS target.getAttribute('translate') is lastAttributeExpectation
+PASS target.translate is initialExpectation
+PASS target.translate is lastExpectation
+PASS target.getAttribute('translate') is lastAttributeExpectation
+PASS target.translate is initialExpectation
+PASS target.translate is lastExpectation
+PASS target.getAttribute('translate') is lastAttributeExpectation
+PASS target.translate is initialExpectation
+PASS target.translate is lastExpectation
+PASS target.getAttribute('translate') is lastAttributeExpectation
+PASS target.translate is initialExpectation
+PASS target.translate is lastExpectation
+PASS target.getAttribute('translate') is lastAttributeExpectation
+PASS target.translate is initialExpectation
+PASS target.translate is lastExpectation
+PASS target.getAttribute('translate') is lastAttributeExpectation
+PASS target.translate is initialExpectation
+PASS target.translate is lastExpectation
+PASS target.getAttribute('translate') is lastAttributeExpectation
+PASS target.translate is initialExpectation
+PASS target.translate is lastExpectation
+PASS target.getAttribute('translate') is lastAttributeExpectation
+PASS target.translate is initialExpectation
+PASS target.translate is lastExpectation
+PASS target.getAttribute('translate') is lastAttributeExpectation
+PASS target.translate is initialExpectation
+PASS target.translate is lastExpectation
+PASS target.getAttribute('translate') is lastAttributeExpectation
+PASS target.translate is initialExpectation
+PASS target.translate is lastExpectation
+PASS target.getAttribute('translate') is lastAttributeExpectation
+PASS target.translate is initialExpectation
+PASS target.translate is lastExpectation
+PASS target.getAttribute('translate') is lastAttributeExpectation
+PASS target.translate is initialExpectation
+PASS target.translate is lastExpectation
+PASS target.getAttribute('translate') is lastAttributeExpectation
+PASS target.translate is initialExpectation
+PASS target.translate is lastExpectation
+PASS target.getAttribute('translate') is lastAttributeExpectation
+PASS target.translate is initialExpectation
+PASS target.translate is lastExpectation
+PASS target.getAttribute('translate') is lastAttributeExpectation
+PASS target.translate is initialExpectation
+PASS target.translate is lastExpectation
+PASS target.getAttribute('translate') is lastAttributeExpectation
+PASS target.translate is initialExpectation
+PASS target.translate is lastExpectation
+PASS target.getAttribute('translate') is lastAttributeExpectation
+PASS target.translate is initialExpectation
+PASS target.translate is lastExpectation
+PASS target.getAttribute('translate') is lastAttributeExpectation
+PASS target.translate is initialExpectation
+PASS target.translate is lastExpectation
+PASS target.getAttribute('translate') is lastAttributeExpectation
+PASS target.translate is initialExpectation
+PASS target.translate is lastExpectation
+PASS target.getAttribute('translate') is lastAttributeExpectation
+PASS target.translate is initialExpectation
+PASS target.translate is lastExpectation
+PASS target.getAttribute('translate') is lastAttributeExpectation
+PASS target.translate is initialExpectation
+PASS target.translate is lastExpectation
+PASS target.getAttribute('translate') is lastAttributeExpectation
+PASS target.translate is initialExpectation
+PASS target.translate is lastExpectation
+PASS target.getAttribute('translate') is lastAttributeExpectation
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
diff --git a/LayoutTests/fast/dom/HTMLElement/translate.html b/LayoutTests/fast/dom/HTMLElement/translate.html
new file mode 100644 (file)
index 0000000..3c6a0e7
--- /dev/null
@@ -0,0 +1,151 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<script src="../../js/resources/js-test-pre.js"></script>
+</head>
+<body>
+<script>
+
+description("Test the translate attribute.");
+
+var parent = document.createElement("div");
+document.body.appendChild(parent);
+
+function testFor(initialAttribute, initialExpectation, setValue, lastExpectation, lastAttributeExpectation)
+{
+    var target = document.createElement("span");
+    parent.appendChild(target);
+
+    window.target = target;
+    window.initialExpectation = initialExpectation;
+    window.lastExpectation = lastExpectation;
+    window.lastAttributeExpectation = lastAttributeExpectation;
+
+    if (undefined !== initialAttribute)
+        target.setAttribute("translate", initialAttribute);
+    shouldBe("target.translate", "initialExpectation");
+
+    if (undefined !== setValue)
+        target.translate = setValue;
+    shouldBe("target.translate", "lastExpectation");
+    shouldBe("target.getAttribute('translate')", "lastAttributeExpectation");
+
+    parent.removeChild(target);
+}
+
+window.target = document.createElement("p");
+parent.appendChild(target);
+
+debug('translate should be "yes" by default.');
+shouldBeTrue("target.translate");
+shouldBeNull("target.getAttribute('translate')");
+
+debug('\ntarget.translate = false;');
+target.translate = false;
+shouldBeFalse("target.translate");
+shouldBeEqualToString("target.getAttribute('translate')", "no");
+
+debug('\ntarget.setAttribute("translate", "yes");');
+target.setAttribute("translate", "yes");
+shouldBeTrue("target.translate");
+shouldBeEqualToString("target.getAttribute('translate')", "yes");
+
+debug('\ntarget.setAttribute("translate", "no");');
+target.setAttribute("translate", "no");
+shouldBeFalse("target.translate");
+shouldBeEqualToString("target.getAttribute('translate')", "no");
+
+debug('\ntarget.setAttribute("translate", "YES");');
+target.setAttribute("translate", "YES");
+shouldBeTrue("target.translate");
+shouldBeEqualToString("target.getAttribute('translate')", "YES");
+
+debug('\ntarget.setAttribute("translate", "NO");');
+target.setAttribute("translate", "NO");
+shouldBeFalse("target.translate");
+shouldBeEqualToString("target.getAttribute('translate')", "NO");
+
+debug('\ntarget.setAttribute("translate", "INVALID");');
+target.setAttribute("translate", "INVALID");
+shouldBeTrue("target.translate");
+shouldBeEqualToString("target.getAttribute('translate')", "INVALID");
+
+debug("\nRemoving translate attribute.");
+target.removeAttribute("translate");
+shouldBeNull("target.getAttribute('translate')");
+shouldBeTrue("target.translate");
+
+debug("\nCreating targetChild element as a child of target.");
+window.targetChild = document.createElement("span");
+target.appendChild(targetChild);
+shouldBeTrue("targetChild.translate");
+shouldBeNull("targetChild.getAttribute('translate')");
+
+debug("\nSetting target.translate = false. targetChild should inherit the translate value from its parents.");
+target.translate = false;
+shouldBeFalse("targetChild.translate");
+shouldBeNull("targetChild.getAttribute('translate')");
+
+debug("\nSetting targetChild.setAttribute('translate', 'INVALID'). Should inherit the translate value from its parents.");
+targetChild.setAttribute("translate", "INVALID");
+shouldBeFalse("target.translate");
+shouldBeEqualToString("target.getAttribute('translate')", "no");
+shouldBeFalse("targetChild.translate");
+shouldBeEqualToString("targetChild.getAttribute('translate')", "INVALID");
+
+debug("\ntargetChild.translate = true;");
+targetChild.translate = true;
+shouldBeTrue("targetChild.translate");
+shouldBeEqualToString("targetChild.getAttribute('translate')", "yes");
+shouldBeFalse("target.translate");
+shouldBeEqualToString("target.getAttribute('translate')", "no");
+
+parent.removeChild(target);
+
+debug("\n");
+
+testFor(undefined, true, undefined, true, null);
+testFor(undefined, true, false, false, "no");
+testFor(undefined, true, true, true, "yes");
+testFor(undefined, true, 0, false, "no"); // 0 will be coerced to false
+testFor(undefined, true, 1, true, "yes"); // 0 will be coerced to true
+testFor(undefined, true, "invalid", true, "yes"); // string will be coerced to true
+testFor(undefined, true, "false", true, "yes"); // ...even if the string is "false" (as Firefox does).
+
+testFor("yes", true, undefined, true, "yes");
+testFor("yes", true, false, false, "no");
+testFor("yes", true, true, true, "yes");
+testFor("yes", true, 0, false, "no");
+testFor("yes", true, 1, true, "yes");
+testFor("yes", true, "invalid", true, "yes");
+testFor("yes", true, "false", true, "yes");
+
+testFor("no", false, undefined, false, "no");
+testFor("no", false, false, false, "no");
+testFor("no", false, true, true, "yes");
+testFor("no", false, 0, false, "no");
+testFor("no", false, 1, true, "yes");
+testFor("no", false, "invalid", true, "yes");
+testFor("no", false, "false", true, "yes");
+
+// various initial values
+testFor("", true, undefined, true, "");
+testFor("", true, 1, true, "yes");
+testFor("YES", true, undefined, true, "YES");
+testFor("YES", true, 1, true, "yes");
+testFor("NO", false, undefined, false, "NO");
+testFor("NO", false, 0, false, "no");
+testFor("invalid", true, undefined, true, "invalid");
+testFor("invalid", true, 1, true, "yes");
+testFor("no  ", true, undefined, true, "no  ");
+testFor("no  ", true, 1, true, "yes");
+testFor("no  ", true, 0, false, "no");
+testFor("0", true, undefined, true, "0");
+testFor("0", true, 0, false, "no");
+testFor("1", true, undefined, true, "1");
+testFor("1", true, 0, false, "no");
+</script>
+<script src="../../js/resources/js-test-post.js"></script>
+</body>
+</html>
index a31f23162639bff821ebf0dab0f03c015811804b..d77cbb5c91e11e14cc2116df10cc0e3961c3cd68 100644 (file)
@@ -1,3 +1,29 @@
+2012-02-15  Pablo Flouret  <pablof@motorola.com>
+
+        Add support for the translate attribute in html elements.
+        https://bugs.webkit.org/show_bug.cgi?id=78751
+
+        Reviewed by Adam Barth.
+
+        The translate attribute is used to specify whether an element's
+        attribute values and the values of its Text node children are to be
+        translated when the page is localized, or whether to leave them
+        unchanged.
+
+        Details at http://www.whatwg.org/specs/web-apps/current-work/multipage/elements.html#attr-translate
+
+        Test: fast/dom/HTMLElement/translate.html
+
+        * html/HTMLAttributeNames.in:
+        * html/HTMLElement.cpp:
+        (WebCore::HTMLElement::translateAttributeMode):
+        (WebCore):
+        (WebCore::HTMLElement::translate):
+        (WebCore::HTMLElement::setTranslate):
+        * html/HTMLElement.h:
+        (HTMLElement):
+        * html/HTMLElement.idl:
+
 2012-02-15  Sami Kyostila  <skyostil@google.com>
 
         Add -webkit-overflow-scrolling CSS property
index 60d96d53d82be81aa2bb051c318dbe5b689b2122..151df7f38a5a5383f295846e32e16bff1a24d18b 100644 (file)
@@ -304,6 +304,7 @@ text
 title
 top
 topmargin
+translate
 truespeed
 type
 usemap
index 27ce832f0cf8f23207d261bf1fa44a3e42d2c7af..7c52727e235aeec657842977561727acc0133627 100644 (file)
@@ -800,6 +800,42 @@ void HTMLElement::setTabIndex(int value)
     setAttribute(tabindexAttr, String::number(value));
 }
 
+TranslateAttributeMode HTMLElement::translateAttributeMode() const
+{
+    const AtomicString& value = getAttribute(translateAttr);
+
+    if (value == nullAtom)
+        return TranslateAttributeInherit;
+    if (equalIgnoringCase(value, "yes") || equalIgnoringCase(value, ""))
+        return TranslateAttributeYes;
+    if (equalIgnoringCase(value, "no"))
+        return TranslateAttributeNo;
+
+    return TranslateAttributeInherit;
+}
+
+bool HTMLElement::translate() const
+{
+    for (const Node* n = this; n; n = n->parentNode()) {
+        if (n->isHTMLElement()) {
+            TranslateAttributeMode mode = static_cast<const HTMLElement*>(n)->translateAttributeMode();
+            if (mode != TranslateAttributeInherit) {
+                ASSERT(mode == TranslateAttributeYes || mode == TranslateAttributeNo);
+                return mode == TranslateAttributeYes;
+            }
+        }
+    }
+
+    // Default on the root element is translate=yes.
+    return true;
+}
+
+void HTMLElement::setTranslate(bool enable)
+{
+    setAttribute(translateAttr, enable ? "yes" : "no");
+}
+
+
 HTMLCollection* HTMLElement::children()
 {
     return ensureCachedHTMLCollection(NodeChildren);
index 5db8d94b0b88925968ba1d71c1af5158d7449e58..bd9be7df479fc3adcfabee8212b4b2948cb38381 100644 (file)
@@ -35,6 +35,12 @@ class HTMLFormElement;
 class MicroDataItemValue;
 #endif
 
+enum TranslateAttributeMode {
+    TranslateAttributeYes,
+    TranslateAttributeNo,
+    TranslateAttributeInherit
+};
+
 class HTMLElement : public StyledElement {
 public:
     static PassRefPtr<HTMLElement> create(const QualifiedName& tagName, Document*);
@@ -68,6 +74,9 @@ public:
     bool spellcheck() const;
     void setSpellcheck(bool);
 
+    bool translate() const;
+    void setTranslate(bool);
+
     void click();
 
     virtual void accessKeyAction(bool sendMouseEvents);
@@ -121,6 +130,8 @@ private:
     void adjustDirectionalityIfNeededAfterChildrenChanged(Node* beforeChange, int childCountDelta);
     TextDirection directionality(Node** strongDirectionalityTextNode= 0) const;
 
+    TranslateAttributeMode translateAttributeMode() const;
+
 #if ENABLE(MICRODATA)
     virtual String itemValueText() const;
     virtual void setItemValueText(const String&, ExceptionCode&);
index b73b4d082dbe861eedeef35a1ea6ebbb13f494b8..8d5a0688d95fa765765fafa9dcb8bb5a5d73328c 100644 (file)
@@ -30,6 +30,7 @@ module html {
                  attribute [Reflect] DOMString id;
                  attribute [Reflect] DOMString title;
                  attribute [Reflect] DOMString lang;
+                 attribute boolean             translate;
                  attribute [Reflect] DOMString dir;
                  attribute [Reflect=class] DOMString className;
                  readonly attribute DOMTokenList classList;