Commit cee5666a authored by Xiaowu Zhang's avatar Xiaowu Zhang

improve indexeddb get/set

parent 38d20eed
...@@ -120,6 +120,12 @@ ...@@ -120,6 +120,12 @@
return jio_gadget.remove.apply(jio_gadget, param_list); return jio_gadget.remove.apply(jio_gadget, param_list);
}); });
} }
}).allowPublicAcquisition("jio_removeAttachment", function(param_list) {
if (this.storageType === 0) {
return this.getDeclaredGadget(storageType(this.storageType)).push(function(jio_gadget) {
return jio_gadget.removeAttachment.apply(jio_gadget, param_list);
});
}
}).allowPublicAcquisition("displayThisTitle", function(param_list) { }).allowPublicAcquisition("displayThisTitle", function(param_list) {
var header = this.__element.getElementsByTagName("h1")[0]; var header = this.__element.getElementsByTagName("h1")[0];
header.innerHTML = param_list[0]; header.innerHTML = param_list[0];
......
...@@ -50,6 +50,9 @@ ...@@ -50,6 +50,9 @@
}).declareMethod("remove", function() { }).declareMethod("remove", function() {
var storage = this.state_parameter_dict.jio_storage; var storage = this.state_parameter_dict.jio_storage;
return storage.remove.apply(storage, arguments); return storage.remove.apply(storage, arguments);
}).declareMethod("removeAttachment", function() {
var storage = this.state_parameter_dict.jio_storage;
return storage.removeAttachment.apply(storage, arguments);
}).declareMethod("put", function() { }).declareMethod("put", function() {
var storage = this.state_parameter_dict.jio_storage; var storage = this.state_parameter_dict.jio_storage;
return storage.put.apply(storage, arguments); return storage.put.apply(storage, arguments);
......
...@@ -122,22 +122,13 @@ ...@@ -122,22 +122,13 @@
}).push(function(value) { }).push(function(value) {
value = value || 5e3; value = value || 5e3;
g.filter.frequency.value = value; g.filter.frequency.value = value;
}).push(function() {
g.currentId = options.id; g.currentId = options.id;
return g.jio_get({
_id: options.id
});
}).push(function(result) {
var share_context = g.__element.getElementsByClassName("share")[0];
share_context.href = "https://twitter.com/intent/tweet?hashtags=MusicPlayer&text=" + encodeURI(result.data.title);
g.length = Object.keys(result.data._attachment).length;
return g.displayThisTitle(options.action + " : " + result.data.title);
}).push(function() { }).push(function() {
return g.allDocs({ return g.allDocs({
include_docs: true include_docs: true
}); });
}).push(function(e) { }).push(function(e) {
var list = e.data.rows, id, index, control = "control"; var list = e.data.rows, id, index = 0, control = "control";
if (list.length === 1) { if (list.length === 1) {
id = g.currentId; id = g.currentId;
} else { } else {
...@@ -158,6 +149,15 @@ ...@@ -158,6 +149,15 @@
g.__element.getElementsByClassName("next")[0].href = url; g.__element.getElementsByClassName("next")[0].href = url;
g.index = 0; g.index = 0;
g.id = options.id; g.id = options.id;
return g.jio_get({
_id: options.id
});
}).push(function(result) {
var share_context = g.__element.getElementsByClassName("share")[0];
share_context.href = "https://twitter.com/intent/tweet?hashtags=MusicPlayer&text=" + encodeURI(result.data.title);
g.length = Object.keys(result.data._attachment).length;
return g.displayThisTitle(options.action + " : " + result.data.title);
}).push(function() {
return g.jio_getAttachment({ return g.jio_getAttachment({
_id: options.id, _id: options.id,
_attachment: "enclosure0" _attachment: "enclosure0"
...@@ -172,12 +172,10 @@ ...@@ -172,12 +172,10 @@
}).push(undefined, function(error) { }).push(undefined, function(error) {
if (!(error instanceof RSVP.CancellationError)) { if (!(error instanceof RSVP.CancellationError)) {
window.location = g.__element.getElementsByClassName("next")[0].href; window.location = g.__element.getElementsByClassName("next")[0].href;
if (error.status === 404 && error.method === "getAttachment") {
return g.jio_remove({ return g.jio_remove({
_id: error.id _id: error.id
}); });
} }
}
}); });
} }
}).declareMethod("startService", function() { }).declareMethod("startService", function() {
...@@ -215,7 +213,6 @@ ...@@ -215,7 +213,6 @@
_id: g.id, _id: g.id,
_attachment: "enclosure" + g.index _attachment: "enclosure" + g.index
}).then(function(blob) { }).then(function(blob) {
console.log(g.index);
return jIO.util.readBlobAsArrayBuffer(blob); return jIO.util.readBlobAsArrayBuffer(blob);
}).then(function(e) { }).then(function(e) {
g.fin = true; g.fin = true;
...@@ -229,7 +226,7 @@ ...@@ -229,7 +226,7 @@
}); });
}), loopEventListener(g.audio, "ended", false, function() { }), loopEventListener(g.audio, "ended", false, function() {
if (loop) { if (loop) {
g.audio.load(); g.audio.currentTime = 0;
g.audio.play(); g.audio.play();
} else { } else {
window.location = g.__element.getElementsByClassName("next")[0].href; window.location = g.__element.getElementsByClassName("next")[0].href;
......
...@@ -4,7 +4,7 @@ ...@@ -4,7 +4,7 @@
(function(window, rJS, $, Handlebars, loopEventListener) { (function(window, rJS, $, Handlebars, loopEventListener) {
"use strict"; "use strict";
var gk = rJS(window), rows_template_source = gk.__template_element.getElementById("rows-template").innerHTML, rows_template = Handlebars.compile(rows_template_source); var gk = rJS(window), rows_template_source = gk.__template_element.getElementById("rows-template").innerHTML, rows_template = Handlebars.compile(rows_template_source);
gk.declareAcquiredMethod("allDocs", "allDocs").declareAcquiredMethod("jio_remove", "jio_remove").declareAcquiredMethod("displayThisPage", "displayThisPage").declareAcquiredMethod("displayThisTitle", "displayThisTitle").declareAcquiredMethod("plEnablePage", "plEnablePage").declareAcquiredMethod("pleaseRedirectMyHash", "pleaseRedirectMyHash").declareMethod("render", function(options) { gk.declareAcquiredMethod("allDocs", "allDocs").declareAcquiredMethod("jio_remove", "jio_remove").declareAcquiredMethod("jio_removeAttachment", "jio_removeAttachment").declareAcquiredMethod("displayThisPage", "displayThisPage").declareAcquiredMethod("displayThisTitle", "displayThisTitle").declareAcquiredMethod("plEnablePage", "plEnablePage").declareAcquiredMethod("pleaseRedirectMyHash", "pleaseRedirectMyHash").declareMethod("render", function(options) {
var gadget = this, list = gadget.__element.getElementsByTagName("ul")[0]; var gadget = this, list = gadget.__element.getElementsByTagName("ul")[0];
return new RSVP.Queue().push(function() { return new RSVP.Queue().push(function() {
return RSVP.all([ gadget.displayThisPage({ return RSVP.all([ gadget.displayThisPage({
......
...@@ -21,7 +21,7 @@ ...@@ -21,7 +21,7 @@
var g = this, input_context = g.__element.getElementsByTagName("input")[0], info_context = g.__element.getElementsByClassName("info")[0], queue, uploaded = 0, post, length; var g = this, input_context = g.__element.getElementsByTagName("input")[0], info_context = g.__element.getElementsByClassName("info")[0], queue, uploaded = 0, post, length;
info_context.innerHTML = "<ul>"; info_context.innerHTML = "<ul>";
function putAll(id, index, file) { function putAll(id, index, file) {
var blobLength = 2e6, size = blobLength * (index + 1), blob; var blobLength = 4e6, size = blobLength * (index + 1), blob;
if (size > file.size) { if (size > file.size) {
blob = file.slice(blobLength * index, file.size); blob = file.slice(blobLength * index, file.size);
} else { } else {
...@@ -67,7 +67,7 @@ ...@@ -67,7 +67,7 @@
return putAll(id, 0, input_context.files[uploaded]); return putAll(id, 0, input_context.files[uploaded]);
}).fail(function(error) { }).fail(function(error) {
if (!(error instanceof RSVP.CancellationError)) { if (!(error instanceof RSVP.CancellationError)) {
info_context.innerHTML += input_context.files[uploaded].name + " failed : storage maybe insufficient"; info_context.innerHTML += input_context.files[uploaded].name + " " + error.target.error.name;
//xxx //xxx
g.plEnablePage(); g.plEnablePage();
return g.jio_remove({ return g.jio_remove({
......
...@@ -9283,9 +9283,16 @@ function sequence(thens) { ...@@ -9283,9 +9283,16 @@ function sequence(thens) {
} }
} }
function transactionEnd(transaction) {
var resolver;
resolver = function (resolve, reject) {
transaction.onabort = reject;
transaction.oncomplete = function () {
resolve("end");
};
};
return new RSVP.Promise(resolver);
}
/** /**
* get a data from a store object * get a data from a store object
* @param {ObjectStore} store The objectstore * @param {ObjectStore} store The objectstore
...@@ -9313,8 +9320,12 @@ function sequence(thens) { ...@@ -9313,8 +9320,12 @@ function sequence(thens) {
function removeIndexedDB(store, id) { function removeIndexedDB(store, id) {
function resolver(resolve, reject) { function resolver(resolve, reject) {
var request = store["delete"](id); var request = store["delete"](id);
request.onerror = reject; request.onerror = function (e) {
request.onsuccess = resolve; reject("remove error");
};
request.onsuccess = function (e){
resolve(request.result);
};
} }
return new RSVP.Promise(resolver); return new RSVP.Promise(resolver);
} }
...@@ -9382,18 +9393,19 @@ function sequence(thens) { ...@@ -9382,18 +9393,19 @@ function sequence(thens) {
//create an id in attachment si necessary //create an id in attachment si necessary
if (researchResult.result === undefined) { if (researchResult.result === undefined) {
return putIndexedDB(researchResult.store, {"_id": metadata._id}); return putIndexedDB(researchResult.store, {"_id": metadata._id});
} else {
return end(result);
} }
}) })
.push(function () {
return transactionEnd(transaction);
})
.push(function () { .push(function () {
return end(result); return end(result);
}) })
.push(undefined, function (error) { .push(undefined, function (error) {
// Check if transaction is ongoing, if so, abort it // Check if transaction is ongoing, if so, abort it
if (transaction !== undefined) { // if (transaction !== undefined) {
transaction.abort(); // transaction.abort();
} // }
if (global_db !== undefined) { if (global_db !== undefined) {
global_db.close(); global_db.close();
} }
...@@ -9441,13 +9453,16 @@ function sequence(thens) { ...@@ -9441,13 +9453,16 @@ function sequence(thens) {
if (result._attachment) { if (result._attachment) {
meta._attachment = result._attachment; meta._attachment = result._attachment;
} }
return transactionEnd(transaction);
})
.push(function () {
return ({"data": meta}); return ({"data": meta});
}) })
.push(undefined, function (error) { .push(undefined, function (error) {
// Check if transaction is ongoing, if so, abort it // Check if transaction is ongoing, if so, abort it
if (transaction !== undefined) { // if (transaction !== undefined) {
transaction.abort(); // transaction.abort();
} // }
if (global_db !== undefined) { if (global_db !== undefined) {
global_db.close(); global_db.close();
} }
...@@ -9468,6 +9483,14 @@ function sequence(thens) { ...@@ -9468,6 +9483,14 @@ function sequence(thens) {
transaction, transaction,
global_db, global_db,
queue = new RSVP.Queue(); queue = new RSVP.Queue();
function tmp(index, array, store) {
return removeIndexedDB(store, [param._id, array[index]])
.then(function (e) {
if (index < array.length -1) {
return tmp(index + 1, array, store);
}
});
};
return queue.push(function () { return queue.push(function () {
return openIndexedDB(jio_storage._database_name); return openIndexedDB(jio_storage._database_name);
}) })
...@@ -9491,15 +9514,10 @@ function sequence(thens) { ...@@ -9491,15 +9514,10 @@ function sequence(thens) {
}) })
.push(function (result) { .push(function (result) {
if (result._attachment) { if (result._attachment) {
var i, l, key, array, func, store; var array, store;
array = Object.keys(result._attachment); array = Object.keys(result._attachment);
store = transaction.objectStore("blob"); store = transaction.objectStore("blob");
for (i = 0, l = array.length; i < l; i += 1) { return tmp(0, array, store);
key = array[i];
//delete blob
func = removeIndexedDB(store, [param._id, key]);
queue.push(func);
}
} }
}) })
.push(function () { .push(function () {
...@@ -9507,14 +9525,17 @@ function sequence(thens) { ...@@ -9507,14 +9525,17 @@ function sequence(thens) {
//delete attachment //delete attachment
return removeIndexedDB(store, param._id); return removeIndexedDB(store, param._id);
}) })
.push(function () {
return transactionEnd(transaction);
})
.push(function () { .push(function () {
return ({"status": 204}); return ({"status": 204});
}) })
.push(undefined, function (error) { .push(undefined, function (error) {
// Check if transaction is ongoing, if so, abort it // Check if transaction is ongoing, if so, abort it
if (transaction !== undefined) { // if (transaction !== undefined) {
transaction.abort(); // transaction.abort();
} // }
if (global_db !== undefined) { if (global_db !== undefined) {
global_db.close(); global_db.close();
} }
...@@ -9762,14 +9783,18 @@ function sequence(thens) { ...@@ -9762,14 +9783,18 @@ function sequence(thens) {
return putIndexedDB(store, {"_id": metadata._id, return putIndexedDB(store, {"_id": metadata._id,
"_attachment" : metadata._attachment, "_attachment" : metadata._attachment,
"blob": metadata._blob}, readResult); "blob": metadata._blob}, readResult);
}).push(function () { })
.push(function () {
return transactionEnd(transaction);
})
.push(function () {
return {"status": 204}; return {"status": 204};
}) })
.push(undefined, function (error) { .push(undefined, function (error) {
// Check if transaction is ongoing, if so, abort it // Check if transaction is ongoing, if so, abort it
if (transaction !== undefined) { // if (transaction !== undefined) {
transaction.abort(); // transaction.abort();
} // }
if (global_db !== undefined) { if (global_db !== undefined) {
global_db.close(); global_db.close();
} }
...@@ -9872,15 +9897,18 @@ function sequence(thens) { ...@@ -9872,15 +9897,18 @@ function sequence(thens) {
delete result._attachment[param._attachment]; delete result._attachment[param._attachment];
var store = transaction.objectStore("attachment"); var store = transaction.objectStore("attachment");
return putIndexedDB(store, result); return putIndexedDB(store, result);
})
.push(function () {
return transactionEnd(transaction);
}) })
.push(function () { .push(function () {
return ({ "status": 204 }); return ({ "status": 204 });
}) })
.push(undefined, function (error) { .push(undefined, function (error) {
// Check if transaction is ongoing, if so, abort it // Check if transaction is ongoing, if so, abort it
if (transaction !== undefined) { // if (transaction !== undefined) {
transaction.abort(); // transaction.abort();
} // }
if (global_db !== undefined) { if (global_db !== undefined) {
global_db.close(); global_db.close();
} }
...@@ -9979,13 +10007,16 @@ decodeURI, encodeURI*/ ...@@ -9979,13 +10007,16 @@ decodeURI, encodeURI*/
result = result.substring(index + 7); result = result.substring(index + 7);
index = result.indexOf("\">"); index = result.indexOf("\">");
url = result.substring(0, index); url = result.substring(0, index);
if (url.indexOf(".mp3") === -1 && url.indexOf(".webm") === -1) { if (url.indexOf(".mp3") === -1 && url.indexOf(".mp4") === -1
&& url.indexOf(".webm") === -1) {
result = result.substring(index + 2); result = result.substring(index + 2);
} else { } else {
if (url.indexOf(".webm") !== -1) { if (url.indexOf(".mp4") !== -1) {
type = "video/webm"; type = "video/mp4";
} else if (url.indexOf(".webm") !== -1 ) {
type = "audio/webm"
} else { } else {
type = "audio/mp3" type = "audio/mp3";
} }
name = decodeURI(url); name = decodeURI(url);
rows.push({ rows.push({
......
...@@ -140,6 +140,14 @@ ...@@ -140,6 +140,14 @@
}); });
} }
}) })
.allowPublicAcquisition("jio_removeAttachment", function (param_list) {
if (this.storageType === 0) {
return this.getDeclaredGadget(storageType(this.storageType))
.push(function (jio_gadget) {
return jio_gadget.removeAttachment.apply(jio_gadget, param_list);
});
}
})
.allowPublicAcquisition("displayThisTitle", function (param_list) { .allowPublicAcquisition("displayThisTitle", function (param_list) {
var header = this.__element.getElementsByTagName("h1")[0]; var header = this.__element.getElementsByTagName("h1")[0];
header.innerHTML = param_list[0]; header.innerHTML = param_list[0];
......
...@@ -64,6 +64,10 @@ ...@@ -64,6 +64,10 @@
var storage = this.state_parameter_dict.jio_storage; var storage = this.state_parameter_dict.jio_storage;
return storage.remove.apply(storage, arguments); return storage.remove.apply(storage, arguments);
}) })
.declareMethod('removeAttachment', function () {
var storage = this.state_parameter_dict.jio_storage;
return storage.removeAttachment.apply(storage, arguments);
})
.declareMethod('put', function () { .declareMethod('put', function () {
var storage = this.state_parameter_dict.jio_storage; var storage = this.state_parameter_dict.jio_storage;
return storage.put.apply(storage, arguments); return storage.put.apply(storage, arguments);
......
...@@ -178,19 +178,7 @@ ...@@ -178,19 +178,7 @@
.push(function (value) { .push(function (value) {
value = value || 5000; value = value || 5000;
g.filter.frequency.value = value; g.filter.frequency.value = value;
})
.push(function () {
g.currentId = options.id; g.currentId = options.id;
return g.jio_get({"_id" : options.id});
})
.push(function (result) {
var share_context = g.__element.getElementsByClassName("share")[0];
share_context.href =
"https://twitter.com/intent/tweet?hashtags=MusicPlayer&text="
+ encodeURI(result.data.title);
g.length = Object.keys(result.data._attachment).length;
return g.displayThisTitle(options.action + " : "
+ result.data.title);
}) })
.push(function () { .push(function () {
return g.allDocs({"include_docs": true}); return g.allDocs({"include_docs": true});
...@@ -198,7 +186,7 @@ ...@@ -198,7 +186,7 @@
.push(function (e) { .push(function (e) {
var list = e.data.rows, var list = e.data.rows,
id, id,
index, index = 0,
control = "control"; control = "control";
if (list.length === 1) { if (list.length === 1) {
id = g.currentId; id = g.currentId;
...@@ -219,6 +207,18 @@ ...@@ -219,6 +207,18 @@
g.__element.getElementsByClassName("next")[0].href = url; g.__element.getElementsByClassName("next")[0].href = url;
g.index = 0; g.index = 0;
g.id = options.id; g.id = options.id;
return g.jio_get({"_id" : options.id});
})
.push(function (result) {
var share_context = g.__element.getElementsByClassName("share")[0];
share_context.href =
"https://twitter.com/intent/tweet?hashtags=MusicPlayer&text="
+ encodeURI(result.data.title);
g.length = Object.keys(result.data._attachment).length;
return g.displayThisTitle(options.action + " : "
+ result.data.title);
})
.push(function () {
return g.jio_getAttachment({"_id" : options.id, return g.jio_getAttachment({"_id" : options.id,
"_attachment" : "enclosure0" }); "_attachment" : "enclosure0" });
}) })
...@@ -234,11 +234,8 @@ ...@@ -234,11 +234,8 @@
if (!(error instanceof RSVP.CancellationError)) { if (!(error instanceof RSVP.CancellationError)) {
window.location = g.__element window.location = g.__element
.getElementsByClassName("next")[0].href; .getElementsByClassName("next")[0].href;
if ((error.status === 404)
&& (error.method === "getAttachment")) {
return g.jio_remove({"_id" : error.id}); return g.jio_remove({"_id" : error.id});
} }
}
}); });
} }
}) })
...@@ -293,7 +290,6 @@ ...@@ -293,7 +290,6 @@
return g.jio_getAttachment({"_id" : g.id, return g.jio_getAttachment({"_id" : g.id,
"_attachment" : "enclosure" + g.index }) "_attachment" : "enclosure" + g.index })
.then(function (blob) { .then(function (blob) {
console.log(g.index);
return jIO.util.readBlobAsArrayBuffer(blob); return jIO.util.readBlobAsArrayBuffer(blob);
}) })
.then(function (e) { .then(function (e) {
...@@ -302,7 +298,6 @@ ...@@ -302,7 +298,6 @@
}); });
}), }),
loopEventListener(mute_context, "click", false, function () { loopEventListener(mute_context, "click", false, function () {
mute_context.innerHTML = g.gain.gain.value ? mute_context.innerHTML = g.gain.gain.value ?
"mute on" : "mute off"; "mute on" : "mute off";
...@@ -312,7 +307,7 @@ ...@@ -312,7 +307,7 @@
loopEventListener(g.audio, "ended", false, function () { loopEventListener(g.audio, "ended", false, function () {
if (loop) { if (loop) {
g.audio.load(); g.audio.currentTime = 0;
g.audio.play(); g.audio.play();
} else { } else {
window.location = g.__element window.location = g.__element
......
...@@ -11,6 +11,7 @@ ...@@ -11,6 +11,7 @@
rows_template = Handlebars.compile(rows_template_source); rows_template = Handlebars.compile(rows_template_source);
gk.declareAcquiredMethod("allDocs", "allDocs") gk.declareAcquiredMethod("allDocs", "allDocs")
.declareAcquiredMethod("jio_remove", "jio_remove") .declareAcquiredMethod("jio_remove", "jio_remove")
.declareAcquiredMethod("jio_removeAttachment", "jio_removeAttachment")
.declareAcquiredMethod("displayThisPage", "displayThisPage") .declareAcquiredMethod("displayThisPage", "displayThisPage")
.declareAcquiredMethod("displayThisTitle", "displayThisTitle") .declareAcquiredMethod("displayThisTitle", "displayThisTitle")
.declareAcquiredMethod("plEnablePage", "plEnablePage") .declareAcquiredMethod("plEnablePage", "plEnablePage")
......
...@@ -40,7 +40,7 @@ ...@@ -40,7 +40,7 @@
length; length;
info_context.innerHTML = "<ul>"; info_context.innerHTML = "<ul>";
function putAll(id, index, file) { function putAll(id, index, file) {
var blobLength = 2000000, var blobLength = 4000000,
size = blobLength * (index + 1), size = blobLength * (index + 1),
blob; blob;
if (size > file.size) { if (size > file.size) {
...@@ -96,8 +96,8 @@ ...@@ -96,8 +96,8 @@
.fail(function (error) { .fail(function (error) {
if (!(error instanceof RSVP.CancellationError)) { if (!(error instanceof RSVP.CancellationError)) {
info_context.innerHTML += info_context.innerHTML +=
input_context.files[uploaded].name + input_context.files[uploaded].name + " " +
" failed : storage maybe insufficient"; error.target.error.name;
//xxx //xxx
g.plEnablePage(); g.plEnablePage();
return g.jio_remove({"_id" : id}); return g.jio_remove({"_id" : id});
......
...@@ -49,7 +49,7 @@ ...@@ -49,7 +49,7 @@
.push(function (e) { .push(function (e) {
var list = e.data.rows, var list = e.data.rows,
id, id,
index, index = 0,
control = "control"; control = "control";
if (list.length === 1) { if (list.length === 1) {
id = g.currentId; id = g.currentId;
...@@ -96,6 +96,9 @@ ...@@ -96,6 +96,9 @@
.declareMethod("startService", function () { .declareMethod("startService", function () {
var g = this; var g = this;
return new RSVP.Queue() return new RSVP.Queue()
.push(function () {
return g.plEnablePage();
})
.push(function () { .push(function () {
return RSVP.any([ return RSVP.any([
loopEventListener(g.sourceBuffer, "updateend", false, function () { loopEventListener(g.sourceBuffer, "updateend", false, function () {
...@@ -111,7 +114,6 @@ ...@@ -111,7 +114,6 @@
return g.jio_getAttachment({"_id" : g.id, return g.jio_getAttachment({"_id" : g.id,
"_attachment" : "enclosure" + g.index }) "_attachment" : "enclosure" + g.index })
.then(function (blob) { .then(function (blob) {
console.log(g.index);
return jIO.util.readBlobAsArrayBuffer(blob); return jIO.util.readBlobAsArrayBuffer(blob);
}) })
.then(function (e) { .then(function (e) {
......
...@@ -29,8 +29,6 @@ ...@@ -29,8 +29,6 @@
<div data-role="footer" data-position="fixed" data-theme="b"> <div data-role="footer" data-position="fixed" data-theme="b">
<div data-role="navbar"> <div data-role="navbar">
<ul> <ul>
<li><a data-role="button" class="mute" data-icon="info" >mute off</a></li>
<li><a data-role="button" class="command" data-icon="gear">stop</a></li>
<li><a data-role="button" class="next" data-icon="arrow-r">next(random)</a></li> <li><a data-role="button" class="next" data-icon="arrow-r">next(random)</a></li>
<li><a data-role="button" class="share" data-icon="star" target="_blank">share</a></li> <li><a data-role="button" class="share" data-icon="star" target="_blank">share</a></li>
</ul> </ul>
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment