[Web Widget] Update Web Widget guide 67/130867/3
authorEditor Lionbridge <TizenEditor.SEL@lionbridge.com>
Wed, 24 May 2017 07:48:24 +0000 (10:48 +0300)
committerEditor Lionbridge <TizenEditor.SEL@lionbridge.com>
Wed, 24 May 2017 08:07:50 +0000 (08:07 +0000)
This is a manual cherry-pick from the #123966 and #130630 changes
in the tizen_3.0 branch.

PS2: Fixed whitespace issues

Change-Id: I9ad567862962584a3c9d965d4fffc8f5a1632aa2

org.tizen.guides/html/web/app_management/web_widget_ww.htm

index 945537b..8b8ef35 100644 (file)
                        <li><a href="#ui_design">UI Design</a></li>
                        <li><a href="#event">Event Handling</a></li>
                        <li><a href="#communication">Communication Between Web Widgets and Other Applications</a></li>
+                       <li><a href="#cookbook">Locale Information Formatting</a></li>
                        <li><a href="#debug">Debugging</a></li>
                        <li><a href="#performance">Performance Considerations</a></li>
                        <li><a href="#faq">FAQ</a></li>
                </ul>
+               <p class="toc-title">Related Info</p>
+               <ul class="toc">
+                       <li><a href="https://developer.tizen.org/dev-guide/2.3.2/org.tizen.web.apireference/html/widget_spec/web_widget.html">Tizen Wearable Web Widget Specification</a></li>
+               </ul>
        </div></div>
 </div>
 
 <pre class="prettyprint">
 &lt;head&gt;
    &lt;style&gt;
-      body
-      {
+      body {
          margin: 0px;
          text-align: center;
       }
-      #content
-      {
+      #content {
          margin-top: 10px;
          padding-left: 33px;
          padding-right: 33px;
 <pre class="prettyprint">
 &lt;head&gt;
    &lt;style&gt;
-      body
-      {
+      body {
          text-align: center;
       }
-      #secondDiv
-      {
+      #secondDiv {
          padding-top: 10px; padding-bottom: 10px;
       }
    &lt;/style&gt;
 
 <pre class="prettyprint">
 &lt;style&gt;
-   body
-   {
+   body {
       text-align: center;
    }
 &lt;/style&gt;
 <pre class="prettyprint">
 &lt;head&gt;
    &lt;style&gt;
-      body
-      {
+      body {
          text-align: center;
       }
-      #largeImage
-      {
+      #largeImage {
          width: 150px; height: 150px;
       }
    &lt;/style&gt;
        <strong>Note</strong>
        The widget engine only supports the <code>block</code>, <code>inline</code>, <code>inline-block</code>, and <code>none</code> values for the <code>display</code> property.
 <pre class="prettyprint">
-#more
-{
+#more {
    .display: inline-block;
 }
 </pre>
 <pre class="prettyprint">
 &lt;head&gt;
    &lt;style&gt;
-      #leftDiv
-      {
+      #leftDiv {
          text-align: right;
       }
-      #rightDiv
-      {
+      #rightDiv {
          text-align: left;
       }
-      .split
-      {
+      .split {
          display: inline-block;
          width: 45%; height: 100%;
       }
-      .imgArea
-      {
+      .imgArea {
          width: 50px; height: 100px;
       }
    &lt;/style&gt;
 <pre class="prettyprint">
 &lt;head&gt;
    &lt;style&gt;
-      body
-      {
+      body {
          width: 360px; height: 360px; margin: 0;
       }
-      .box
-      {
+      .box {
          position: absolute;
          width: 100px; height: 100px;
       }
-      #topDiv
-      {
+      #topDiv {
          left: 130px; /* (360/2)-(100/2) */
       }
-      #leftDiv
-      {
+      #leftDiv {
          top: 100px;
       }
-      #rightDiv
-      {
+      #rightDiv {
          top: 100px;
          left: 260px; /* 360-100 */
       }
-      #bottomDiv
-      {
+      #bottomDiv {
          top: 200px;
          left: 130px; /* (360/2)-(100/2) */
       }
 <pre class="prettyprint">
 &lt;head&gt;
    &lt;style&gt;
-      body
-      {
+      body {
          width: 360px; height: 360px; margin: 0;
       }
-      .box
-      {
+      .box {
          width: 100px; height: 100px;
          display: inline-block;
       }
-      #topDiv, #midDiv, #bottomDiv
-      {
+      #topDiv, #midDiv, #bottomDiv {
          text-align: center;
       }
-      #leftDiv
-      {
+      #leftDiv {
          margin-right: 50px;
       }
-      #rightDiv
-      {
+      #rightDiv {
          margin-left: 50px;
       }
    &lt;/style&gt;
 <p>You can set the widget content styles, such as font and border, by changing the CSS properties. For example, you can set the font and border properties as follows:</p>
 
 <pre class="prettyprint">
-#text
-{
+#text {
    font-size: 20pt;
    font-weight: bold; /* Available values: normal, bold, bolder, lighter, number */
    text-align: center;
 }
-
-#more
-{
+#more {
    border-style: solid;
    border-left-color: lightgray;
    border-top-color: lightgray;
 &lt;/html&gt;
 
 &lt;!--CSS--&gt;
-#viewport
-{
+#viewport {
    font-size: 20pt;
    text-align: center;
 }
-#day
-{
+#day {
    color: green;
    font-size: 30pt;
 }
-#scheduleTitle
-{
+#scheduleTitle {
    margin-top: 5%;
    height: 13%;
    font-weight: bold;
    font-size: 30pt;
 }
-#more
-{
+#more {
    font-size: 16pt;
    width: 50px;
    display: inline-block;
    border-left-color: lightgray;
    border-top-color: lightgray;
 }
-#scheduleTime, #more
-{
+#scheduleTime, #more {
    margin-top: 2%;
    color: gray;
 }
 &lt;/html&gt;
 
 &lt;!--CSS--&gt;
-body
-{
+body {
    position: absolute;
    width: 360px; height: 360px;
    font-size: 20px;
    text-align: center;
 }
-*
-{
+* {
    display: block;
    margin: 0px; padding: 0px;
 }
-.category
-{
+.category {
    margin-top: 40px;
    margin-left: 137.5px;
 }
-.content
-{
+.content {
    margin-top: 10px;
    padding-left: 33px;
    padding-right: 33px;
    height: 66px;
    font-size: 26px;
 }
-.more
-{
+.more {
    margin-top: 28px;
    height: 20.2px;
 }
 </pre>
 <pre class="prettyprint">
 /* JavaScript */
-function onload()
-{
+function onload() {
    /* Load news data here */
 
    /* Content update */
@@ -678,17 +646,14 @@ function onload()
 <pre class="prettyprint">
 var cntImage = 0;
 
-function step()
-{
+function step() {
    document.getElementById("imgWeather").src = "images/sun_" + (cntImage++) + ".png";
-   if (cntImage &lt; 4)
-   {
+   if (cntImage &lt; 4) {
       window.requestAnimationFrame(step);
    }
 }
 
-function goAni()
-{
+function goAni() {
    window.requestAnimationFrame(step);
 }
 </pre>
@@ -701,18 +666,16 @@ function goAni()
 <pre class="prettyprint">
 var scrollLength = 0;
 
-function step()
-{
+function step() {
+
    document.getElementById('scheduleTitle').style.transform =
       "translateX(" + (scrollLength--) + "px)"
-   if (scrollLength &gt; -300) /* Max length */
-   {
+   if (scrollLength &gt; -300) { /* Max length */
       window.requestAnimationFrame(step);
    }
 }
 
-function goAni()
-{
+function goAni() {
    window.requestAnimationFrame(step);
 }
 </pre>
@@ -742,8 +705,7 @@ object.onload=load;
 object.addEventListener('load', load);
 
 /* Define the event handler in the main.js file */
-function load()
-{
+function load() {
    /* Load water data from shared file */
    loadWaterData();
 
@@ -751,8 +713,7 @@ function load()
    document.getElementById('currentWaterNum').textContent = currentWaterNum;
 
    /* Change the color of the water cups */
-   for (var i = 1; i &lt;= currentWaterNum; ++i)
-   {
+   for (var i = 1; i &lt;= currentWaterNum; ++i) {
       document.getElementById('watercup' + i)).style.backgroundColor = 'blue';
    }
 }
@@ -780,8 +741,7 @@ object.addEventListener('click', click);
 
 /* Define the event handler in the main.js file */
 /* When the user clicks the button, update the status and change the style */
-function click()
-{
+function click() {
    /* Increase the water amount */
    currentWaterNum++;
 
@@ -809,14 +769,10 @@ function click()
 document.addEventListener('visibilitychange', visibilitychange);
 
 /* Define the event handler in the main.js file */
-function visibilitychange()
-{
-   if (document.visibilityState === 'hidden')
-   {
+function visibilitychange() {
+   if (document.visibilityState === 'hidden') {
       /* Store shared data */
-   }
-   else
-   {
+    } else {
       /* Load stored data and update the page */
    }
 }
@@ -888,15 +844,12 @@ function visibilitychange()
 
 <p>The following example shows how to set a key-value pair in the <code>Widget_main.js</code> file:</p>
 <pre class="prettyprint">
-function checkPreference()
-{
-   if (!tizen.preference.exists("KEY"))
-   {
+function checkPreference() {
+   if (!tizen.preference.exists("KEY")) {
       tizen.preference.setValue("KEY", "Widget_HELLOWORLD1");
    }
 
-   if (tizen.preference.exists("KEY"))
-   {
+   if (tizen.preference.exists("KEY")) {
       tizen.preference.remove("KEY");
       tizen.preference.setValue("KEY", "Widget_HELLOWORLD2");
    }
@@ -905,8 +858,7 @@ function checkPreference()
    console.log('value for KEY: ' + tizen.preference.getValue('KEY'));
 
    /* Callback function */
-   var listener = function(data)
-   {
+   var listener = function(data) {
       /* [Log] Preference with the key: KEY has a new value: APP_HELLOWORLD */
       console.log('Preference with the key: ' + data.key
                   + ' has a new value: ' + data.value);
@@ -918,20 +870,14 @@ function checkPreference()
 </pre>
 <p>To set the value in the <code>WebApp_main.js</code> file:</p>
 <pre class="prettyprint">
-window.onload = function()
-{
-   var timer = setInterval(function()
-      {
-         clearInterval(timer);
-         try
-         {
+window.onload = function() {
+   var timer = setInterval(function() {
+      clearInterval(timer);
+         try {
             tizen.preference.setValue("KEY", "APP_HELLOWORLD");
             tizen.application.getCurrentApplication().exit();
-         }
-         catch (ignore)
-         {
-         }
-      }, 2000);
+         } catch (ignore) {}
+   }, 2000);
 };
 </pre>
 
@@ -981,20 +927,16 @@ var SASocket = 0;
 var CHANNELID = 2000;
 var providerAppName = 'WeatherProvider';
 
-function onerror(err)
-{
+function onerror(err) {
    /* Error handling */
 }
 
-var agentCallback =
-{
-   onconnect: function(socket)
-   {
+var agentCallback = {
+   onconnect: function(socket) {
       SASocket = socket;
-      SASocket.setSocketStatusListener(function(reason)
-         {
+      SASocket.setSocketStatusListener(function(reason) {
             disconnect();
-         });
+            });
       SASocket.setDataReceiveListener(onreceive);
       /* Request the provider to get weather info */
       SASocket.sendData(CHANNELID, 'request');
@@ -1002,63 +944,45 @@ var agentCallback =
    onerror: onerror
 };
 
-var peerAgentFindCallback =
-{
-   onpeeragentfound: function(peerAgent)
-   {
-      try
-      {
-         if (peerAgent.appName == providerAppName)
-         {
+var peerAgentFindCallback = {
+   onpeeragentfound: function(peerAgent) {
+        try {
+            if (peerAgent.appName == providerAppName) {
             SAAgent.setServiceConnectionListener(agentCallback);
             SAAgent.requestServiceConnection(peerAgent);
          }
-      }
-      catch (err)
-      {
+       } catch (err) {
          /* Error handling */
       }
    },
    onerror: onerror
 };
 
-function onsuccess(agents)
-{
-   try
-   {
-      if (agents.length &gt; 0)
-      {
+function onsuccess(agents) {
+   try {
+        if (agents.length &gt; 0) {
          SAAgent = agents[0];
          SAAgent.setPeerAgentFindListener(peerAgentFindCallback);
          SAAgent.findPeerAgents();
       }
-   }
-   catch (err)
-   {
+    } catch (err) {
       /* Error handling */
    }
 }
 
-function onreceive(channelId, data)
-{
+function onreceive(channelId, data) {
    document.getElementById('result').textContent = data;
 }
 
-function getDataFromHostApp()
-{
-   if (SASocket)
-   {
+function getDataFromHostApp() {
+   if (SASocket) {
       return false; /* Already connected */
    }
-   try
-   {
-      webapis.sa.requestSAAgent(onsuccess, function(err)
-         {
-            /* Error handling */
-         });
-   }
-   catch (err)
-   {
+   try {
+      webapis.sa.requestSAAgent(onsuccess, function(err) {
+         /* Error handling */
+      });
+   } catch (err) {
       /* Error handling */
    }
 }
@@ -1109,8 +1033,7 @@ try {
       .send(WeatherProviderForWidget.WIDGET_CHANNEL_ID, jsonData.toString().getBytes());
 } catch (JSONException e) {
    e.printStackTrace();
-}
-catch (IOException e_io) {
+} catch (IOException e_io) {
    e_io.printStackTrace();
 }
 
@@ -1180,12 +1103,12 @@ public class WeatherProviderForWidget extends SAAgent {
                e.printStackTrace();
             }
          } else if (req_message.equals(new String("delete_widget"))) {
-               Log.e(TAG, "The widget was deleted from the viewer");
+            Log.e(TAG, "The widget was deleted from the viewer");
          } else if (req_message.equals(new String("Add city"))) {
-               Context context = getApplicationContext();
-               Intent intent = new Intent(context, ProviderActivity.class);
-               intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
-               context.startActivity(intent);
+            Context context = getApplicationContext();
+            Intent intent = new Intent(context, ProviderActivity.class);
+            intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+            context.startActivity(intent);
          }
       }
 
@@ -1202,7 +1125,7 @@ public class WeatherProviderForWidget extends SAAgent {
 
 <h3 id="comm_server">Communicating with a Web Server</h3>
 
-   <p>To get data from a Web server through the Internet, use the XMLHttpRequest API. The Web widget engine, however, does not support the full XMLHttpRequest specification. It supports only the <code>GET</code> method, and the <code>TEXT</code> and <code>JSON</code> data types.</p>
+   <p>To get data from a Web server through the Internet, use the XMLHttpRequest API. The Web widget engine, however, does not support the full XMLHttpRequest specification. It only supports the <code>GET</code> and <code>POST</code> methods, and the <code>TEXT</code> and <code>JSON</code> data types. This design decision emphasizes the read-only behavior of the Web widgets and meets the runtime memory requirements. Use Web widgets to display information in a compact manner, and do not create new resources using the <code>PUT</code> method: as user interaction is not intended and can exceed the widget's maximum allowed memory, it can lead to security risks.</p>
    <p>The following example shows Web widget communication with a Web server:</p>
 
 <pre class="prettyprint">
@@ -1221,66 +1144,63 @@ public class WeatherProviderForWidget extends SAAgent {
 
 <pre class="prettyprint">
 /* JavaScript */
-function errorHandling(e)
-{
-   if (e.target.readyState == 3)
-   {
+function errorHandling(e) {
+   if (e.target.readyState == 3) {
       /* Error handling */
       e.target.abort();
    }
 }
 
-function getDataFromNetwork(file, handler)
-{
+function getDataFromNetwork(file, handler) {
    var xhr = new XMLHttpRequest();
    xhr.open('GET', file, true);
    xhr.onreadystatechange = handler;
-   xhr.onload = function()
-   {
-      if (this.status == 200)
-      {
+   xhr.onload = function() {
+      if (this.status == 200) {
          /* Handle the response */
       }
    };
    xhr.send();
 }
 
-/* In case of getting Text data */
-function handleResponseTEXT(e)
-{
-   if (e.target.readyState == 4)
-   {
-      if (e.target.status == 200)
-      {
+/* If getting Text data */
+function handleResponseTEXT(e) {
+   if (e.target.readyState == 4) {
+      if (e.target.status == 200) {
          document.getElementById('result').textContent = e.target.responseText;
-      }
-      else
-      {
+      } else {
          /* Error handling */
       }
    }
 }
 
-/* In case of getting JSON data */
-function handleResponseJSON(e)
-{
-   if (e.target.readyState == 4)
-   {
-      if (e.target.status == 200)
-      {
+/* If getting JSON data */
+function handleResponseJSON(e) {
+   if (e.target.readyState == 4) {
+      if (e.target.status == 200) {
          var data = JSON.parse(e.target.responseText);
          var val = data.employees;
          var result = val[0].firstName + ' ' + val[0].lastName;
          document.getElementById('result').textContent = result;
-      }
-      else
-      {
+      } else {
          /* Error handling */
       }
    }
 }
 </pre>
 
+<h2 id="cookbook">Locale Information Formatting</h2>
+
+<p>You can use a <code>Date</code> object to format locale information in a widget.</p>
+
+<p>The following example provides the date information in different formats:</p>
+
+<pre class="prettyprint">
+var d = new Date();
+d.toLocaleString(); /* "2/1/2013 7:37:08 AM" */
+d.toLocaleDateString(); /* "2/1/2013" */
+d.toLocaleTimeString(); /* "7:38:05 AM" */
+</pre>
 
 <h2 id="debug">Debugging</h2>
 
@@ -1374,8 +1294,7 @@ sdb dlog | grep ConsoleMessage
 &lt;link rel="stylesheet" type="text/css" href="http://spec.example.com/theme.css"&gt;
 
 &lt;!--CSS--&gt;
-#myImage
-{
+#myImage {
    content: url('http://spec.example.com/image.png');
 }
 </pre>
@@ -1523,8 +1442,7 @@ sdb dlog | grep ConsoleMessage
 <pre class="prettyprint">
 &lt;!--CSS style--&gt;
 &lt;style&gt;
-   body
-   {
+   body {
       position: absolute;
       margin: 0px;
       padding: 0px;
@@ -1536,22 +1454,16 @@ sdb dlog | grep ConsoleMessage
       color: Black;
       background-color: White;
    }
-
-   #leftDiv
-   {
+   #leftDiv {
       text-align: center;
       border: 1px solid red;
    }
-
-   #rightDiv
-   {
+   #rightDiv {
       text-align: center;
       border: 1px solid red;
       margin-left: -5px;
    }
-
-   .split
-   {
+   .split {
       display: inline-block;
       width: 45%; height: 100%;
    }
@@ -1601,10 +1513,8 @@ var parent = document.getElementById('parentDiv');
 var c = parent.children;
 var i;
 
-for (i = 0; i &lt; c.length; i++)
-{
-   if (c[i].id === 'leftDiv')
-   {
+for (i = 0; i &lt; c.length; i++) {
+   if (c[i].id === 'leftDiv') {
       /* Do something */
    }
 }
@@ -1618,8 +1528,7 @@ for (i = 0; i &lt; c.length; i++)
 var c = document.body.children;
 var i;
 
-for (i = 0; i &lt; c.length; i++)
-{
+for (i = 0; i &lt; c.length; i++) {
    c[i].style.backgroundColor = "red";
 }
 </pre>