initial for RIP prototype/scriptaculous
This commit is contained in:
parent
0b6a71f8ea
commit
70fa423026
|
@ -362,7 +362,6 @@ class Handler_Public extends Handler {
|
||||||
echo javascript_tag("lib/dojo/dojo.js");
|
echo javascript_tag("lib/dojo/dojo.js");
|
||||||
echo javascript_tag("js/utility.js");
|
echo javascript_tag("js/utility.js");
|
||||||
echo javascript_tag("lib/dojo/tt-rss-layer.js");
|
echo javascript_tag("lib/dojo/tt-rss-layer.js");
|
||||||
echo javascript_tag("lib/scriptaculous/scriptaculous.js?load=effects,controls")
|
|
||||||
?>
|
?>
|
||||||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
|
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
|
||||||
<link rel="shortcut icon" type="image/png" href="images/favicon.png">
|
<link rel="shortcut icon" type="image/png" href="images/favicon.png">
|
||||||
|
@ -388,10 +387,10 @@ class Handler_Public extends Handler {
|
||||||
ready(function() {
|
ready(function() {
|
||||||
parser.parse();
|
parser.parse();
|
||||||
|
|
||||||
new Ajax.Autocompleter('labels_value', 'labels_choices',
|
/* new Ajax.Autocompleter('labels_value', 'labels_choices',
|
||||||
"backend.php?op=rpc&method=completeLabels",
|
"backend.php?op=rpc&method=completeLabels",
|
||||||
{ tokens: ',', paramName: "search" });
|
{ tokens: ',', paramName: "search" });
|
||||||
});
|
}); */
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
@ -366,7 +366,7 @@ class Pref_Prefs extends Handler_Protected {
|
||||||
if (warn) Element.hide(warn);
|
if (warn) Element.hide(warn);
|
||||||
}
|
}
|
||||||
|
|
||||||
new Effect.Appear('pwd_change_infobox');
|
Element.show('pwd_change_infobox');
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
|
@ -76,8 +76,7 @@
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<?php
|
<?php
|
||||||
foreach (array("lib/prototype.js",
|
foreach (array(#"lib/_prototype.js",
|
||||||
"lib/scriptaculous/scriptaculous.js?load=effects,controls",
|
|
||||||
"lib/dojo/dojo.js",
|
"lib/dojo/dojo.js",
|
||||||
"lib/dojo/tt-rss-layer.js",
|
"lib/dojo/tt-rss-layer.js",
|
||||||
"js/tt-rss.js",
|
"js/tt-rss.js",
|
||||||
|
|
75
js/App.js
75
js/App.js
|
@ -109,6 +109,15 @@ const App = {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
byId: function(id) {
|
||||||
|
return document.getElementById(id);
|
||||||
|
},
|
||||||
|
find: function(query) {
|
||||||
|
return document.querySelector(query)
|
||||||
|
},
|
||||||
|
findAll: function(query) {
|
||||||
|
return document.querySelectorAll(query);
|
||||||
|
},
|
||||||
dialogOf: function (elem) {
|
dialogOf: function (elem) {
|
||||||
|
|
||||||
// elem could be a Dijit widget
|
// elem could be a Dijit widget
|
||||||
|
@ -140,21 +149,20 @@ const App = {
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
setupNightModeDetection: function(callback) {
|
setupNightModeDetection: function(callback) {
|
||||||
if (!$("theme_css")) {
|
if (!App.byId("theme_css")) {
|
||||||
const mql = window.matchMedia('(prefers-color-scheme: dark)');
|
const mql = window.matchMedia('(prefers-color-scheme: dark)');
|
||||||
|
|
||||||
try {
|
try {
|
||||||
mql.addEventListener("change", () => {
|
mql.addEventListener("change", () => {
|
||||||
this.nightModeChanged(mql.matches, $("theme_auto_css"));
|
this.nightModeChanged(mql.matches, App.byId("theme_auto_css"));
|
||||||
});
|
});
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.warn("exception while trying to set MQL event listener");
|
console.warn("exception while trying to set MQL event listener");
|
||||||
}
|
}
|
||||||
|
|
||||||
const link = new Element("link", {
|
const link = document.createElement("link");
|
||||||
rel: "stylesheet",
|
link.rel = "stylesheet";
|
||||||
id: "theme_auto_css"
|
link.id = "theme_auto_css";
|
||||||
});
|
|
||||||
|
|
||||||
if (callback) {
|
if (callback) {
|
||||||
link.onload = function() {
|
link.onload = function() {
|
||||||
|
@ -176,7 +184,7 @@ const App = {
|
||||||
if (callback) callback();
|
if (callback) callback();
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
enableCsrfSupport: function() {
|
/*enableCsrfSupport: function() {
|
||||||
const _this = this;
|
const _this = this;
|
||||||
|
|
||||||
Ajax.Base.prototype.initialize = Ajax.Base.prototype.initialize.wrap(
|
Ajax.Base.prototype.initialize = Ajax.Base.prototype.initialize.wrap(
|
||||||
|
@ -196,7 +204,7 @@ const App = {
|
||||||
return callOriginal(options);
|
return callOriginal(options);
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
},
|
}, */
|
||||||
postCurrentWindow: function(target, params) {
|
postCurrentWindow: function(target, params) {
|
||||||
const form = document.createElement("form");
|
const form = document.createElement("form");
|
||||||
|
|
||||||
|
@ -245,8 +253,13 @@ const App = {
|
||||||
}
|
}
|
||||||
|
|
||||||
},
|
},
|
||||||
urlParam: function(param) {
|
urlParam: function(name) {
|
||||||
return String(window.location.href).parseQuery()[param];
|
try {
|
||||||
|
const results = new RegExp('[\?&]' + name + '=([^&#]*)').exec(window.location.href);
|
||||||
|
return decodeURIComponent(results[1].replace(/\+/g, " ")) || 0;
|
||||||
|
} catch (e) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
},
|
},
|
||||||
next_seq: function() {
|
next_seq: function() {
|
||||||
this._rpc_seq += 1;
|
this._rpc_seq += 1;
|
||||||
|
@ -262,7 +275,7 @@ const App = {
|
||||||
dijit.byId("loading_bar").update({progress: this._loading_progress});
|
dijit.byId("loading_bar").update({progress: this._loading_progress});
|
||||||
|
|
||||||
if (this._loading_progress >= 90) {
|
if (this._loading_progress >= 90) {
|
||||||
$("overlay").hide();
|
App.byId("overlay").hide();
|
||||||
}
|
}
|
||||||
|
|
||||||
},
|
},
|
||||||
|
@ -293,7 +306,7 @@ const App = {
|
||||||
if (!this.hotkey_prefix && hotkeys_map[0].indexOf(keychar) != -1) {
|
if (!this.hotkey_prefix && hotkeys_map[0].indexOf(keychar) != -1) {
|
||||||
|
|
||||||
this.hotkey_prefix = keychar;
|
this.hotkey_prefix = keychar;
|
||||||
$("cmdline").innerHTML = keychar;
|
App.byId("cmdline").innerHTML = keychar;
|
||||||
Element.show("cmdline");
|
Element.show("cmdline");
|
||||||
|
|
||||||
window.clearTimeout(this.hotkey_prefix_timeout);
|
window.clearTimeout(this.hotkey_prefix_timeout);
|
||||||
|
@ -342,11 +355,11 @@ const App = {
|
||||||
cleanupMemory: function(root) {
|
cleanupMemory: function(root) {
|
||||||
const dijits = dojo.query("[widgetid]", dijit.byId(root).domNode).map(dijit.byNode);
|
const dijits = dojo.query("[widgetid]", dijit.byId(root).domNode).map(dijit.byNode);
|
||||||
|
|
||||||
dijits.each(function (d) {
|
dijits.forEach(function (d) {
|
||||||
dojo.destroy(d.domNode);
|
dojo.destroy(d.domNode);
|
||||||
});
|
});
|
||||||
|
|
||||||
$$("#" + root + " *").each(function (i) {
|
App.findAll("#" + root + " *").forEach(function (i) {
|
||||||
i.parentNode ? i.parentNode.removeChild(i) : true;
|
i.parentNode ? i.parentNode.removeChild(i) : true;
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
@ -364,9 +377,9 @@ const App = {
|
||||||
},
|
},
|
||||||
displayIfChecked: function(checkbox, elemId) {
|
displayIfChecked: function(checkbox, elemId) {
|
||||||
if (checkbox.checked) {
|
if (checkbox.checked) {
|
||||||
Effect.Appear(elemId, {duration : 0.5});
|
Element.show(elemId);
|
||||||
} else {
|
} else {
|
||||||
Effect.Fade(elemId, {duration : 0.5});
|
Element.hide(elemId);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
hotkeyHelp: function() {
|
hotkeyHelp: function() {
|
||||||
|
@ -381,7 +394,7 @@ const App = {
|
||||||
},
|
},
|
||||||
handleRpcJson: function(transport) {
|
handleRpcJson: function(transport) {
|
||||||
|
|
||||||
const netalert = $$("#toolbar .net-alert")[0];
|
const netalert = App.findAll("#toolbar .net-alert")[0];
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const reply = JSON.parse(transport.responseText);
|
const reply = JSON.parse(transport.responseText);
|
||||||
|
@ -459,7 +472,7 @@ const App = {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (k == "recent_log_events") {
|
if (k == "recent_log_events") {
|
||||||
const alert = $$(".log-alert")[0];
|
const alert = App.findAll(".log-alert")[0];
|
||||||
|
|
||||||
if (alert) {
|
if (alert) {
|
||||||
v > 0 ? alert.show() : alert.hide();
|
v > 0 ? alert.show() : alert.hide();
|
||||||
|
@ -516,7 +529,7 @@ const App = {
|
||||||
break;
|
break;
|
||||||
case "cdm_auto_catchup":
|
case "cdm_auto_catchup":
|
||||||
if (params[k] == 1) {
|
if (params[k] == 1) {
|
||||||
const hl = $("headlines-frame");
|
const hl = App.byId("headlines-frame");
|
||||||
if (hl) hl.addClassName("auto_catchup");
|
if (hl) hl.addClassName("auto_catchup");
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -562,7 +575,7 @@ const App = {
|
||||||
}
|
}
|
||||||
|
|
||||||
return this.report(error,
|
return this.report(error,
|
||||||
Object.extend({title: __("Fatal error")}, params));
|
{...{title: __("Fatal error")}, ...params});
|
||||||
},
|
},
|
||||||
report: function(error, params = {}) {
|
report: function(error, params = {}) {
|
||||||
if (!error) return;
|
if (!error) return;
|
||||||
|
@ -650,7 +663,7 @@ const App = {
|
||||||
|
|
||||||
this.setLoadingProgress(30);
|
this.setLoadingProgress(30);
|
||||||
this.initHotkeyActions();
|
this.initHotkeyActions();
|
||||||
this.enableCsrfSupport();
|
//this.enableCsrfSupport();
|
||||||
|
|
||||||
const params = {
|
const params = {
|
||||||
op: "rpc",
|
op: "rpc",
|
||||||
|
@ -671,7 +684,7 @@ const App = {
|
||||||
checkBrowserFeatures: function() {
|
checkBrowserFeatures: function() {
|
||||||
let errorMsg = "";
|
let errorMsg = "";
|
||||||
|
|
||||||
['MutationObserver'].each(function(wf) {
|
['MutationObserver'].forEach(function(wf) {
|
||||||
if (!(wf in window)) {
|
if (!(wf in window)) {
|
||||||
errorMsg = `Browser feature check failed: <code>window.${wf}</code> not found.`;
|
errorMsg = `Browser feature check failed: <code>window.${wf}</code> not found.`;
|
||||||
throw new Error(errorMsg);
|
throw new Error(errorMsg);
|
||||||
|
@ -794,9 +807,9 @@ const App = {
|
||||||
console.log('update reply', reply);
|
console.log('update reply', reply);
|
||||||
|
|
||||||
if (reply.id) {
|
if (reply.id) {
|
||||||
$("updates-available").show();
|
App.byId("updates-available").show();
|
||||||
} else {
|
} else {
|
||||||
$("updates-available").hide();
|
App.byId("updates-available").hide();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
@ -812,7 +825,7 @@ const App = {
|
||||||
onViewModeChanged: function() {
|
onViewModeChanged: function() {
|
||||||
const view_mode = document.forms["toolbar-main"].view_mode.value;
|
const view_mode = document.forms["toolbar-main"].view_mode.value;
|
||||||
|
|
||||||
$$("body")[0].setAttribute("view-mode", view_mode);
|
App.findAll("body")[0].setAttribute("view-mode", view_mode);
|
||||||
|
|
||||||
return Feeds.reloadCurrent('');
|
return Feeds.reloadCurrent('');
|
||||||
},
|
},
|
||||||
|
@ -851,8 +864,8 @@ const App = {
|
||||||
{width: Cookie.get("ttrss_ci_width") + "px" });
|
{width: Cookie.get("ttrss_ci_width") + "px" });
|
||||||
}
|
}
|
||||||
|
|
||||||
$("headlines-frame").setStyle({ borderBottomWidth: '0px' });
|
App.byId("headlines-frame").setStyle({ borderBottomWidth: '0px' });
|
||||||
$("headlines-frame").addClassName("wide");
|
App.byId("headlines-frame").addClassName("wide");
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
|
@ -867,8 +880,8 @@ const App = {
|
||||||
{height: Cookie.get("ttrss_ci_height") + "px" });
|
{height: Cookie.get("ttrss_ci_height") + "px" });
|
||||||
}
|
}
|
||||||
|
|
||||||
$("headlines-frame").setStyle({ borderBottomWidth: '1px' });
|
App.byId("headlines-frame").setStyle({ borderBottomWidth: '1px' });
|
||||||
$("headlines-frame").removeClassName("wide");
|
App.byId("headlines-frame").removeClassName("wide");
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1107,7 +1120,7 @@ const App = {
|
||||||
this.hotkey_actions["select_article_cursor"] = () => {
|
this.hotkey_actions["select_article_cursor"] = () => {
|
||||||
const id = Article.getUnderPointer();
|
const id = Article.getUnderPointer();
|
||||||
if (id) {
|
if (id) {
|
||||||
const row = $("RROW-" + id);
|
const row = App.byId("RROW-" + id);
|
||||||
|
|
||||||
if (row)
|
if (row)
|
||||||
row.toggleClassName("Selected");
|
row.toggleClassName("Selected");
|
||||||
|
@ -1234,7 +1247,7 @@ const App = {
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case "qmcHKhelp":
|
case "qmcHKhelp":
|
||||||
this.hotkeyHelp();
|
this.helpDialog("main");
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
console.log("quickMenuGo: unknown action: " + opid);
|
console.log("quickMenuGo: unknown action: " + opid);
|
||||||
|
|
|
@ -36,19 +36,19 @@ const Article = {
|
||||||
const score = prompt(__("Please enter new score for selected articles:"));
|
const score = prompt(__("Please enter new score for selected articles:"));
|
||||||
|
|
||||||
if (!isNaN(parseInt(score))) {
|
if (!isNaN(parseInt(score))) {
|
||||||
ids.each((id) => {
|
ids.forEach((id) => {
|
||||||
const row = $("RROW-" + id);
|
const row = App.byId("RROW-" + id);
|
||||||
|
|
||||||
if (row) {
|
if (row) {
|
||||||
row.setAttribute("data-score", score);
|
row.setAttribute("data-score", score);
|
||||||
|
|
||||||
const pic = row.select(".icon-score")[0];
|
const pic = row.querySelector(".icon-score");
|
||||||
|
|
||||||
pic.innerHTML = Article.getScorePic(score);
|
pic.innerHTML = Article.getScorePic(score);
|
||||||
pic.setAttribute("title", score);
|
pic.setAttribute("title", score);
|
||||||
|
|
||||||
["score-low", "score-high", "score-half-low", "score-half-high", "score-neutral"]
|
["score-low", "score-high", "score-half-low", "score-half-high", "score-neutral"]
|
||||||
.each(function(scl) {
|
.forEach(function(scl) {
|
||||||
if (row.hasClassName(scl))
|
if (row.hasClassName(scl))
|
||||||
row.removeClassName(scl);
|
row.removeClassName(scl);
|
||||||
});
|
});
|
||||||
|
@ -72,13 +72,13 @@ const Article = {
|
||||||
if (!isNaN(parseInt(score))) {
|
if (!isNaN(parseInt(score))) {
|
||||||
row.setAttribute("data-score", score);
|
row.setAttribute("data-score", score);
|
||||||
|
|
||||||
const pic = row.select(".icon-score")[0];
|
const pic = row.querySelector(".icon-score");
|
||||||
|
|
||||||
pic.innerHTML = Article.getScorePic(score);
|
pic.innerHTML = Article.getScorePic(score);
|
||||||
pic.setAttribute("title", score);
|
pic.setAttribute("title", score);
|
||||||
|
|
||||||
["score-low", "score-high", "score-half-low", "score-half-high", "score-neutral"]
|
["score-low", "score-high", "score-half-low", "score-half-high", "score-neutral"]
|
||||||
.each(function(scl) {
|
.forEach(function(scl) {
|
||||||
if (row.hasClassName(scl))
|
if (row.hasClassName(scl))
|
||||||
row.removeClassName(scl);
|
row.removeClassName(scl);
|
||||||
});
|
});
|
||||||
|
@ -104,7 +104,7 @@ const Article = {
|
||||||
}
|
}
|
||||||
}, */
|
}, */
|
||||||
cdmUnsetActive: function (event) {
|
cdmUnsetActive: function (event) {
|
||||||
const row = $("RROW-" + Article.getActive());
|
const row = App.byId("RROW-" + Article.getActive());
|
||||||
|
|
||||||
if (row) {
|
if (row) {
|
||||||
row.removeClassName("active");
|
row.removeClassName("active");
|
||||||
|
@ -249,7 +249,7 @@ const Article = {
|
||||||
container.innerHTML += " ";
|
container.innerHTML += " ";
|
||||||
|
|
||||||
// in expandable mode, save content for later, so that we can pack unfocused rows back
|
// in expandable mode, save content for later, so that we can pack unfocused rows back
|
||||||
if (App.isCombinedMode() && $("main").hasClassName("expandable"))
|
if (App.isCombinedMode() && App.byId("main").hasClassName("expandable"))
|
||||||
row.setAttribute("data-content-original", row.getAttribute("data-content"));
|
row.setAttribute("data-content-original", row.getAttribute("data-content"));
|
||||||
|
|
||||||
row.removeAttribute("data-content");
|
row.removeAttribute("data-content");
|
||||||
|
@ -351,7 +351,7 @@ const Article = {
|
||||||
if (data) {
|
if (data) {
|
||||||
const id = data.id;
|
const id = data.id;
|
||||||
|
|
||||||
const tags = $("ATSTR-" + id);
|
const tags = App.byId("ATSTR-" + id);
|
||||||
const tooltip = dijit.byId("ATSTRTIP-" + id);
|
const tooltip = dijit.byId("ATSTRTIP-" + id);
|
||||||
|
|
||||||
if (tags) tags.innerHTML = data.content;
|
if (tags) tags.innerHTML = data.content;
|
||||||
|
@ -370,13 +370,13 @@ const Article = {
|
||||||
|
|
||||||
xhrJson("backend.php", {op: "article", method: "printArticleTags", id: id}, (reply) => {
|
xhrJson("backend.php", {op: "article", method: "printArticleTags", id: id}, (reply) => {
|
||||||
|
|
||||||
dijit.getEnclosingWidget($("tags_str"))
|
dijit.getEnclosingWidget(App.byId("tags_str"))
|
||||||
.attr('value', reply.tags.join(", "))
|
.attr('value', reply.tags.join(", "))
|
||||||
.attr('disabled', false);
|
.attr('disabled', false);
|
||||||
|
|
||||||
new Ajax.Autocompleter("tags_str", "tags_choices",
|
/* new Ajax.Autocompleter("tags_str", "tags_choices",
|
||||||
"backend.php?op=article&method=completeTags",
|
"backend.php?op=article&method=completeTags",
|
||||||
{tokens: ',', paramName: "search"});
|
{tokens: ',', paramName: "search"}); */
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -386,8 +386,8 @@ const Article = {
|
||||||
cdmMoveToId: function (id, params = {}) {
|
cdmMoveToId: function (id, params = {}) {
|
||||||
const force_to_top = params.force_to_top || false;
|
const force_to_top = params.force_to_top || false;
|
||||||
|
|
||||||
const ctr = $("headlines-frame");
|
const ctr = App.byId("headlines-frame");
|
||||||
const row = $("RROW-" + id);
|
const row = App.byId("RROW-" + id);
|
||||||
|
|
||||||
if (!row || !ctr) return;
|
if (!row || !ctr) return;
|
||||||
|
|
||||||
|
@ -399,12 +399,12 @@ const Article = {
|
||||||
if (id != Article.getActive()) {
|
if (id != Article.getActive()) {
|
||||||
console.log("setActive", id, "was", Article.getActive());
|
console.log("setActive", id, "was", Article.getActive());
|
||||||
|
|
||||||
$$("div[id*=RROW][class*=active]").each((row) => {
|
App.findAll("div[id*=RROW][class*=active]").forEach((row) => {
|
||||||
row.removeClassName("active");
|
row.removeClassName("active");
|
||||||
Article.pack(row);
|
Article.pack(row);
|
||||||
});
|
});
|
||||||
|
|
||||||
const row = $("RROW-" + id);
|
const row = App.byId("RROW-" + id);
|
||||||
|
|
||||||
if (row) {
|
if (row) {
|
||||||
Article.unpack(row);
|
Article.unpack(row);
|
||||||
|
@ -425,10 +425,10 @@ const Article = {
|
||||||
return 0;
|
return 0;
|
||||||
},
|
},
|
||||||
scrollByPages: function (page_offset) {
|
scrollByPages: function (page_offset) {
|
||||||
App.Scrollable.scrollByPages($("content-insert"), page_offset);
|
App.Scrollable.scrollByPages(App.byId("content-insert"), page_offset);
|
||||||
},
|
},
|
||||||
scroll: function (offset) {
|
scroll: function (offset) {
|
||||||
App.Scrollable.scroll($("content-insert"), offset);
|
App.Scrollable.scroll(App.byId("content-insert"), offset);
|
||||||
},
|
},
|
||||||
mouseIn: function (id) {
|
mouseIn: function (id) {
|
||||||
this.post_under_pointer = id;
|
this.post_under_pointer = id;
|
||||||
|
|
|
@ -25,7 +25,7 @@ const CommonDialogs = {
|
||||||
else
|
else
|
||||||
Feeds.reload();
|
Feeds.reload();
|
||||||
|
|
||||||
const icon = $$(".feed-editor-icon")[0];
|
const icon = App.findAll(".feed-editor-icon")[0];
|
||||||
|
|
||||||
if (icon)
|
if (icon)
|
||||||
icon.src = icon.src.replace(/\?[0-9]+$/, "?" + new Date().getTime());
|
icon.src = icon.src.replace(/\?[0-9]+$/, "?" + new Date().getTime());
|
||||||
|
@ -36,7 +36,7 @@ const CommonDialogs = {
|
||||||
return false;
|
return false;
|
||||||
},
|
},
|
||||||
uploadFeedIcon: function() {
|
uploadFeedIcon: function() {
|
||||||
const file = $("icon_file");
|
const file = App.byId("icon_file");
|
||||||
|
|
||||||
if (file.value.length == 0) {
|
if (file.value.length == 0) {
|
||||||
alert(__("Please select an image file to upload."));
|
alert(__("Please select an image file to upload."));
|
||||||
|
@ -57,7 +57,7 @@ const CommonDialogs = {
|
||||||
else
|
else
|
||||||
Feeds.reload();
|
Feeds.reload();
|
||||||
|
|
||||||
const icon = $$(".feed-editor-icon")[0];
|
const icon = App.findAll(".feed-editor-icon")[0];
|
||||||
|
|
||||||
if (icon)
|
if (icon)
|
||||||
icon.src = icon.src.replace(/\?[0-9]+$/, "?" + new Date().getTime());
|
icon.src = icon.src.replace(/\?[0-9]+$/, "?" + new Date().getTime());
|
||||||
|
@ -72,7 +72,7 @@ const CommonDialogs = {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
xhr.send(new FormData($("feed_icon_upload_form")));
|
xhr.send(new FormData(App.byId("feed_icon_upload_form")));
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
|
@ -165,13 +165,11 @@ const CommonDialogs = {
|
||||||
</form>
|
</form>
|
||||||
`,
|
`,
|
||||||
show_error: function (msg) {
|
show_error: function (msg) {
|
||||||
const elem = $("fadd_error_message");
|
const elem = App.byId("fadd_error_message");
|
||||||
|
|
||||||
elem.innerHTML = msg;
|
elem.innerHTML = msg;
|
||||||
|
|
||||||
if (!Element.visible(elem))
|
Element.show(elem);
|
||||||
new Effect.Appear(elem);
|
|
||||||
|
|
||||||
},
|
},
|
||||||
execute: function () {
|
execute: function () {
|
||||||
if (this.validate()) {
|
if (this.validate()) {
|
||||||
|
@ -239,7 +237,7 @@ const CommonDialogs = {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Effect.Appear('feedDlg_feedsContainer', {duration: 0.5});
|
Element.show('feedDlg_feedsContainer');
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 5:
|
case 5:
|
||||||
|
@ -463,8 +461,6 @@ const CommonDialogs = {
|
||||||
target.href = new_link;
|
target.href = new_link;
|
||||||
target.innerHTML = new_link;
|
target.innerHTML = new_link;
|
||||||
|
|
||||||
new Effect.Highlight(target);
|
|
||||||
|
|
||||||
Notify.close();
|
Notify.close();
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
@ -528,8 +524,6 @@ const CommonDialogs = {
|
||||||
target.href = target.href.replace(/&key=.*$/,
|
target.href = target.href.replace(/&key=.*$/,
|
||||||
"&key=" + new_link);
|
"&key=" + new_link);
|
||||||
|
|
||||||
new Effect.Highlight(target);
|
|
||||||
|
|
||||||
Notify.close();
|
Notify.close();
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -9,7 +9,7 @@ const Filters = {
|
||||||
filterDlgCheckAction: function(sender) {
|
filterDlgCheckAction: function(sender) {
|
||||||
const action = sender.value;
|
const action = sender.value;
|
||||||
|
|
||||||
const action_param = $("filterDlg_paramBox");
|
const action_param = App.byId("filterDlg_paramBox");
|
||||||
|
|
||||||
if (!action_param) {
|
if (!action_param) {
|
||||||
console.log("filterDlgCheckAction: can't find action param box!");
|
console.log("filterDlgCheckAction: can't find action param box!");
|
||||||
|
@ -18,7 +18,7 @@ const Filters = {
|
||||||
|
|
||||||
// if selected action supports parameters, enable params field
|
// if selected action supports parameters, enable params field
|
||||||
if (action == 4 || action == 6 || action == 7 || action == 9) {
|
if (action == 4 || action == 6 || action == 7 || action == 9) {
|
||||||
new Effect.Appear(action_param, {duration: 0.5});
|
Element.show(action_param);
|
||||||
|
|
||||||
Element.hide(dijit.byId("filterDlg_actionParam").domNode);
|
Element.hide(dijit.byId("filterDlg_actionParam").domNode);
|
||||||
Element.hide(dijit.byId("filterDlg_actionParamLabel").domNode);
|
Element.hide(dijit.byId("filterDlg_actionParamLabel").domNode);
|
||||||
|
@ -97,7 +97,7 @@ const Filters = {
|
||||||
title: ruleStr ? __("Edit rule") : __("Add rule"),
|
title: ruleStr ? __("Edit rule") : __("Add rule"),
|
||||||
execute: function () {
|
execute: function () {
|
||||||
if (this.validate()) {
|
if (this.validate()) {
|
||||||
Filters.createNewRuleElement($("filterDlg_Matches"), replaceNode);
|
Filters.createNewRuleElement(App.byId("filterDlg_Matches"), replaceNode);
|
||||||
this.hide();
|
this.hide();
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
@ -119,7 +119,7 @@ const Filters = {
|
||||||
title: actionStr ? __("Edit action") : __("Add action"),
|
title: actionStr ? __("Edit action") : __("Add action"),
|
||||||
execute: function () {
|
execute: function () {
|
||||||
if (this.validate()) {
|
if (this.validate()) {
|
||||||
Filters.createNewActionElement($("filterDlg_Actions"), replaceNode);
|
Filters.createNewActionElement(App.byId("filterDlg_Actions"), replaceNode);
|
||||||
this.hide();
|
this.hide();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -158,7 +158,7 @@ const Filters = {
|
||||||
|
|
||||||
console.log("got results:" + result.length);
|
console.log("got results:" + result.length);
|
||||||
|
|
||||||
$("prefFilterProgressMsg").innerHTML = __("Looking for articles (%d processed, %f found)...")
|
App.byId("prefFilterProgressMsg").innerHTML = __("Looking for articles (%d processed, %f found)...")
|
||||||
.replace("%f", dialog.results)
|
.replace("%f", dialog.results)
|
||||||
.replace("%d", offset);
|
.replace("%d", offset);
|
||||||
|
|
||||||
|
@ -167,7 +167,7 @@ const Filters = {
|
||||||
for (let i = 0; i < result.length; i++) {
|
for (let i = 0; i < result.length; i++) {
|
||||||
const tmp = dojo.create("table", { innerHTML: result[i]});
|
const tmp = dojo.create("table", { innerHTML: result[i]});
|
||||||
|
|
||||||
$("prefFilterTestResultList").innerHTML += tmp.innerHTML;
|
App.byId("prefFilterTestResultList").innerHTML += tmp.innerHTML;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (dialog.results < 30 && offset < dialog.max_offset) {
|
if (dialog.results < 30 && offset < dialog.max_offset) {
|
||||||
|
@ -183,11 +183,11 @@ const Filters = {
|
||||||
Element.hide("prefFilterLoadingIndicator");
|
Element.hide("prefFilterLoadingIndicator");
|
||||||
|
|
||||||
if (dialog.results == 0) {
|
if (dialog.results == 0) {
|
||||||
$("prefFilterTestResultList").innerHTML = `<tr><td align='center'>
|
App.byId("prefFilterTestResultList").innerHTML = `<tr><td align='center'>
|
||||||
${__('No recent articles matching this filter have been found.')}</td></tr>`;
|
${__('No recent articles matching this filter have been found.')}</td></tr>`;
|
||||||
$("prefFilterProgressMsg").innerHTML = "Articles matching this filter:";
|
App.byId("prefFilterProgressMsg").innerHTML = "Articles matching this filter:";
|
||||||
} else {
|
} else {
|
||||||
$("prefFilterProgressMsg").innerHTML = __("Found %d articles matching this filter:")
|
App.byId("prefFilterProgressMsg").innerHTML = __("Found %d articles matching this filter:")
|
||||||
.replace("%d", dialog.results);
|
.replace("%d", dialog.results);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -289,12 +289,12 @@ const Filters = {
|
||||||
Filters.addFilterRule();
|
Filters.addFilterRule();
|
||||||
},
|
},
|
||||||
deleteAction: function () {
|
deleteAction: function () {
|
||||||
$$("#filterDlg_Actions li[class*=Selected]").each(function (e) {
|
App.findAll("#filterDlg_Actions li[class*=Selected]").forEach(function (e) {
|
||||||
e.parentNode.removeChild(e)
|
e.parentNode.removeChild(e)
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
deleteRule: function () {
|
deleteRule: function () {
|
||||||
$$("#filterDlg_Matches li[class*=Selected]").each(function (e) {
|
App.findAll("#filterDlg_Matches li[class*=Selected]").forEach(function (e) {
|
||||||
e.parentNode.removeChild(e)
|
e.parentNode.removeChild(e)
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
|
@ -286,7 +286,7 @@ define(["dojo/_base/declare", "dojo/dom-construct", "dojo/_base/array", "dojo/co
|
||||||
|
|
||||||
// focus headlines to route key events there
|
// focus headlines to route key events there
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
$("headlines-frame").focus();
|
App.byId("headlines-frame").focus();
|
||||||
|
|
||||||
if (treeNode) {
|
if (treeNode) {
|
||||||
const node = treeNode.rowNode;
|
const node = treeNode.rowNode;
|
||||||
|
@ -295,7 +295,7 @@ define(["dojo/_base/declare", "dojo/dom-construct", "dojo/_base/array", "dojo/co
|
||||||
if (node && tree) {
|
if (node && tree) {
|
||||||
// scroll tree to selection if needed
|
// scroll tree to selection if needed
|
||||||
if (node.offsetTop < tree.scrollTop || node.offsetTop > tree.scrollTop + tree.clientHeight) {
|
if (node.offsetTop < tree.scrollTop || node.offsetTop > tree.scrollTop + tree.clientHeight) {
|
||||||
$("feedTree").scrollTop = node.offsetTop;
|
App.byId("feedTree").scrollTop = node.offsetTop;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
20
js/Feeds.js
20
js/Feeds.js
|
@ -117,7 +117,7 @@ const Feeds = {
|
||||||
toggle: function() {
|
toggle: function() {
|
||||||
Element.toggle("feeds-holder");
|
Element.toggle("feeds-holder");
|
||||||
|
|
||||||
const splitter = $("feeds-holder_splitter");
|
const splitter = App.byId("feeds-holder_splitter");
|
||||||
|
|
||||||
Element.visible("feeds-holder") ? splitter.show() : splitter.hide();
|
Element.visible("feeds-holder") ? splitter.show() : splitter.hide();
|
||||||
|
|
||||||
|
@ -180,7 +180,7 @@ const Feeds = {
|
||||||
dojo.disconnect(tmph);
|
dojo.disconnect(tmph);
|
||||||
});
|
});
|
||||||
|
|
||||||
$("feeds-holder").appendChild(tree.domNode);
|
App.byId("feeds-holder").appendChild(tree.domNode);
|
||||||
|
|
||||||
const tmph2 = dojo.connect(tree, 'onLoad', function () {
|
const tmph2 = dojo.connect(tree, 'onLoad', function () {
|
||||||
dojo.disconnect(tmph2);
|
dojo.disconnect(tmph2);
|
||||||
|
@ -284,8 +284,8 @@ const Feeds = {
|
||||||
this._active_feed_id = id;
|
this._active_feed_id = id;
|
||||||
this._active_feed_is_cat = is_cat;
|
this._active_feed_is_cat = is_cat;
|
||||||
|
|
||||||
$("headlines-frame").setAttribute("feed-id", id);
|
App.byId("headlines-frame").setAttribute("feed-id", id);
|
||||||
$("headlines-frame").setAttribute("is-cat", is_cat ? 1 : 0);
|
App.byId("headlines-frame").setAttribute("is-cat", is_cat ? 1 : 0);
|
||||||
|
|
||||||
this.select(id, is_cat);
|
this.select(id, is_cat);
|
||||||
|
|
||||||
|
@ -310,8 +310,8 @@ const Feeds = {
|
||||||
if (tree)
|
if (tree)
|
||||||
return tree.hideRead(hide, App.getInitParam("hide_read_shows_special"));*/
|
return tree.hideRead(hide, App.getInitParam("hide_read_shows_special"));*/
|
||||||
|
|
||||||
$$("body")[0].setAttribute("hide-read-feeds", !!hide);
|
App.findAll("body")[0].setAttribute("hide-read-feeds", !!hide);
|
||||||
$$("body")[0].setAttribute("hide-read-shows-special", !!App.getInitParam("hide_read_shows_special"));
|
App.findAll("body")[0].setAttribute("hide-read-shows-special", !!App.getInitParam("hide_read_shows_special"));
|
||||||
},
|
},
|
||||||
open: function(params) {
|
open: function(params) {
|
||||||
const feed = params.feed;
|
const feed = params.feed;
|
||||||
|
@ -339,7 +339,7 @@ const Feeds = {
|
||||||
}, 10 * 1000);
|
}, 10 * 1000);
|
||||||
}
|
}
|
||||||
|
|
||||||
Form.enable("toolbar-main");
|
//Form.enable("toolbar-main");
|
||||||
|
|
||||||
let query = Object.assign({op: "feeds", method: "view", feed: feed},
|
let query = Object.assign({op: "feeds", method: "view", feed: feed},
|
||||||
dojo.formToObject("toolbar-main"));
|
dojo.formToObject("toolbar-main"));
|
||||||
|
@ -362,7 +362,7 @@ const Feeds = {
|
||||||
query.m = "ForceUpdate";
|
query.m = "ForceUpdate";
|
||||||
}
|
}
|
||||||
|
|
||||||
Form.enable("toolbar-main");
|
//Form.enable("toolbar-main");
|
||||||
|
|
||||||
if (!delayed)
|
if (!delayed)
|
||||||
if (!this.setExpando(feed, is_cat,
|
if (!this.setExpando(feed, is_cat,
|
||||||
|
@ -476,9 +476,9 @@ const Feeds = {
|
||||||
|
|
||||||
if (App.getInitParam("confirm_feed_catchup") != 1 || confirm(str)) {
|
if (App.getInitParam("confirm_feed_catchup") != 1 || confirm(str)) {
|
||||||
|
|
||||||
const rows = $$("#headlines-frame > div[id*=RROW][class*=Unread][data-orig-feed-id='" + id + "']");
|
const rows = App.findAll("#headlines-frame > div[id*=RROW][class*=Unread][data-orig-feed-id='" + id + "']");
|
||||||
|
|
||||||
rows.each((row) => {
|
rows.forEach((row) => {
|
||||||
row.removeClassName("Unread");
|
row.removeClassName("Unread");
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
171
js/Headlines.js
171
js/Headlines.js
|
@ -44,7 +44,7 @@ const Headlines = {
|
||||||
row_observer: new MutationObserver((mutations) => {
|
row_observer: new MutationObserver((mutations) => {
|
||||||
const modified = [];
|
const modified = [];
|
||||||
|
|
||||||
mutations.each((m) => {
|
mutations.forEach((m) => {
|
||||||
if (m.type == 'attributes' && ['class', 'data-score'].indexOf(m.attributeName) != -1) {
|
if (m.type == 'attributes' && ['class', 'data-score'].indexOf(m.attributeName) != -1) {
|
||||||
|
|
||||||
const row = m.target;
|
const row = m.target;
|
||||||
|
@ -54,7 +54,7 @@ const Headlines = {
|
||||||
const hl = Headlines.headlines[id];
|
const hl = Headlines.headlines[id];
|
||||||
|
|
||||||
if (hl) {
|
if (hl) {
|
||||||
const hl_old = Object.extend({}, hl);
|
const hl_old = {...{}, ...hl};
|
||||||
|
|
||||||
hl.unread = row.hasClassName("Unread");
|
hl.unread = row.hasClassName("Unread");
|
||||||
hl.marked = row.hasClassName("marked");
|
hl.marked = row.hasClassName("marked");
|
||||||
|
@ -94,7 +94,7 @@ const Headlines = {
|
||||||
rescore: {},
|
rescore: {},
|
||||||
};
|
};
|
||||||
|
|
||||||
modified.each(function (m) {
|
modified.forEach(function (m) {
|
||||||
if (m.old.marked != m.new.marked)
|
if (m.old.marked != m.new.marked)
|
||||||
ops.tmark.push(m.id);
|
ops.tmark.push(m.id);
|
||||||
|
|
||||||
|
@ -118,29 +118,29 @@ const Headlines = {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
ops.select.each((row) => {
|
ops.select.forEach((row) => {
|
||||||
const cb = dijit.getEnclosingWidget(row.select(".rchk")[0]);
|
const cb = dijit.getEnclosingWidget(row.querySelector(".rchk"));
|
||||||
|
|
||||||
if (cb)
|
if (cb)
|
||||||
cb.attr('checked', true);
|
cb.attr('checked', true);
|
||||||
});
|
});
|
||||||
|
|
||||||
ops.deselect.each((row) => {
|
ops.deselect.forEach((row) => {
|
||||||
const cb = dijit.getEnclosingWidget(row.select(".rchk")[0]);
|
const cb = dijit.getEnclosingWidget(row.querySelector(".rchk"));
|
||||||
|
|
||||||
if (cb && !row.hasClassName("active"))
|
if (cb && !row.hasClassName("active"))
|
||||||
cb.attr('checked', false);
|
cb.attr('checked', false);
|
||||||
});
|
});
|
||||||
|
|
||||||
ops.activate.each((row) => {
|
ops.activate.forEach((row) => {
|
||||||
const cb = dijit.getEnclosingWidget(row.select(".rchk")[0]);
|
const cb = dijit.getEnclosingWidget(row.querySelector(".rchk"));
|
||||||
|
|
||||||
if (cb)
|
if (cb)
|
||||||
cb.attr('checked', true);
|
cb.attr('checked', true);
|
||||||
});
|
});
|
||||||
|
|
||||||
ops.deactivate.each((row) => {
|
ops.deactivate.forEach((row) => {
|
||||||
const cb = dijit.getEnclosingWidget(row.select(".rchk")[0]);
|
const cb = dijit.getEnclosingWidget(row.querySelector(".rchk"));
|
||||||
|
|
||||||
if (cb && !row.hasClassName("Selected"))
|
if (cb && !row.hasClassName("Selected"))
|
||||||
cb.attr('checked', false);
|
cb.attr('checked', false);
|
||||||
|
@ -167,7 +167,7 @@ const Headlines = {
|
||||||
const scores = Object.keys(ops.rescore);
|
const scores = Object.keys(ops.rescore);
|
||||||
|
|
||||||
if (scores.length != 0) {
|
if (scores.length != 0) {
|
||||||
scores.each((score) => {
|
scores.forEach((score) => {
|
||||||
promises.push(xhrPost("backend.php",
|
promises.push(xhrPost("backend.php",
|
||||||
{op: "article", method: "setScore", id: ops.rescore[score].toString(), score: score}));
|
{op: "article", method: "setScore", id: ops.rescore[score].toString(), score: score}));
|
||||||
});
|
});
|
||||||
|
@ -211,7 +211,7 @@ const Headlines = {
|
||||||
|
|
||||||
Headlines.select('none');
|
Headlines.select('none');
|
||||||
|
|
||||||
const scroll_position_A = $("RROW-" + id).offsetTop - $("headlines-frame").scrollTop;
|
const scroll_position_A = App.byId("RROW-" + id).offsetTop - App.byId("headlines-frame").scrollTop;
|
||||||
|
|
||||||
Article.setActive(id);
|
Article.setActive(id);
|
||||||
|
|
||||||
|
@ -222,10 +222,10 @@ const Headlines = {
|
||||||
|
|
||||||
Headlines.toggleUnread(id, 0);
|
Headlines.toggleUnread(id, 0);
|
||||||
} else {
|
} else {
|
||||||
const scroll_position_B = $("RROW-" + id).offsetTop - $("headlines-frame").scrollTop;
|
const scroll_position_B = App.byId("RROW-" + id).offsetTop - App.byId("headlines-frame").scrollTop;
|
||||||
|
|
||||||
// this would only work if there's enough space
|
// this would only work if there's enough space
|
||||||
$("headlines-frame").scrollTop -= scroll_position_A-scroll_position_B;
|
App.byId("headlines-frame").scrollTop -= scroll_position_A-scroll_position_B;
|
||||||
|
|
||||||
Article.cdmMoveToId(id);
|
Article.cdmMoveToId(id);
|
||||||
}
|
}
|
||||||
|
@ -252,7 +252,7 @@ const Headlines = {
|
||||||
return false;
|
return false;
|
||||||
},
|
},
|
||||||
initScrollHandler: function () {
|
initScrollHandler: function () {
|
||||||
$("headlines-frame").onscroll = (event) => {
|
App.byId("headlines-frame").onscroll = (event) => {
|
||||||
clearTimeout(this._headlines_scroll_timeout);
|
clearTimeout(this._headlines_scroll_timeout);
|
||||||
this._headlines_scroll_timeout = window.setTimeout(function () {
|
this._headlines_scroll_timeout = window.setTimeout(function () {
|
||||||
//console.log('done scrolling', event);
|
//console.log('done scrolling', event);
|
||||||
|
@ -262,8 +262,8 @@ const Headlines = {
|
||||||
},
|
},
|
||||||
loadMore: function () {
|
loadMore: function () {
|
||||||
const view_mode = document.forms["toolbar-main"].view_mode.value;
|
const view_mode = document.forms["toolbar-main"].view_mode.value;
|
||||||
const unread_in_buffer = $$("#headlines-frame > div[id*=RROW][class*=Unread]").length;
|
const unread_in_buffer = App.findAll("#headlines-frame > div[id*=RROW][class*=Unread]").length;
|
||||||
const num_all = $$("#headlines-frame > div[id*=RROW]").length;
|
const num_all = App.findAll("#headlines-frame > div[id*=RROW]").length;
|
||||||
const num_unread = Feeds.getUnread(Feeds.getActive(), Feeds.activeIsCat());
|
const num_unread = Feeds.getUnread(Feeds.getActive(), Feeds.activeIsCat());
|
||||||
|
|
||||||
// TODO implement marked & published
|
// TODO implement marked & published
|
||||||
|
@ -289,10 +289,10 @@ const Headlines = {
|
||||||
Feeds.open({feed: Feeds.getActive(), is_cat: Feeds.activeIsCat(), offset: offset, append: true});
|
Feeds.open({feed: Feeds.getActive(), is_cat: Feeds.activeIsCat(), offset: offset, append: true});
|
||||||
},
|
},
|
||||||
isChildVisible: function (elem) {
|
isChildVisible: function (elem) {
|
||||||
return App.Scrollable.isChildVisible(elem, $("headlines-frame"));
|
return App.Scrollable.isChildVisible(elem, App.byId("headlines-frame"));
|
||||||
},
|
},
|
||||||
firstVisible: function () {
|
firstVisible: function () {
|
||||||
const rows = $$("#headlines-frame > div[id*=RROW]");
|
const rows = App.findAll("#headlines-frame > div[id*=RROW]");
|
||||||
|
|
||||||
for (let i = 0; i < rows.length; i++) {
|
for (let i = 0; i < rows.length; i++) {
|
||||||
const row = rows[i];
|
const row = rows[i];
|
||||||
|
@ -303,7 +303,7 @@ const Headlines = {
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
unpackVisible: function(container) {
|
unpackVisible: function(container) {
|
||||||
const rows = $$("#headlines-frame > div[id*=RROW][data-content].cdm");
|
const rows = App.findAll("#headlines-frame > div[id*=RROW][data-content].cdm");
|
||||||
|
|
||||||
for (let i = 0; i < rows.length; i++) {
|
for (let i = 0; i < rows.length; i++) {
|
||||||
if (App.Scrollable.isChildVisible(rows[i], container)) {
|
if (App.Scrollable.isChildVisible(rows[i], container)) {
|
||||||
|
@ -315,8 +315,8 @@ const Headlines = {
|
||||||
scrollHandler: function (/*event*/) {
|
scrollHandler: function (/*event*/) {
|
||||||
try {
|
try {
|
||||||
if (!Feeds.infscroll_disabled && !Feeds.infscroll_in_progress) {
|
if (!Feeds.infscroll_disabled && !Feeds.infscroll_in_progress) {
|
||||||
const hsp = $("headlines-spacer");
|
const hsp = App.byId("headlines-spacer");
|
||||||
const container = $("headlines-frame");
|
const container = App.byId("headlines-frame");
|
||||||
|
|
||||||
if (hsp && hsp.previousSibling) {
|
if (hsp && hsp.previousSibling) {
|
||||||
const last_row = hsp.previousSibling;
|
const last_row = hsp.previousSibling;
|
||||||
|
@ -333,7 +333,7 @@ const Headlines = {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (App.isCombinedMode() && App.getInitParam("cdm_expanded")) {
|
if (App.isCombinedMode() && App.getInitParam("cdm_expanded")) {
|
||||||
const container = $("headlines-frame")
|
const container = App.byId("headlines-frame")
|
||||||
|
|
||||||
/* don't do anything until there was some scrolling */
|
/* don't do anything until there was some scrolling */
|
||||||
if (container.scrollTop > 0)
|
if (container.scrollTop > 0)
|
||||||
|
@ -342,12 +342,12 @@ const Headlines = {
|
||||||
|
|
||||||
if (App.getInitParam("cdm_auto_catchup")) {
|
if (App.getInitParam("cdm_auto_catchup")) {
|
||||||
|
|
||||||
const rows = $$("#headlines-frame > div[id*=RROW][class*=Unread]");
|
const rows = App.findAll("#headlines-frame > div[id*=RROW][class*=Unread]");
|
||||||
|
|
||||||
for (let i = 0; i < rows.length; i++) {
|
for (let i = 0; i < rows.length; i++) {
|
||||||
const row = rows[i];
|
const row = rows[i];
|
||||||
|
|
||||||
if ($("headlines-frame").scrollTop > (row.offsetTop + row.offsetHeight / 2)) {
|
if (App.byId("headlines-frame").scrollTop > (row.offsetTop + row.offsetHeight / 2)) {
|
||||||
row.removeClassName("Unread");
|
row.removeClassName("Unread");
|
||||||
} else {
|
} else {
|
||||||
break;
|
break;
|
||||||
|
@ -362,23 +362,23 @@ const Headlines = {
|
||||||
return this.headlines[id];
|
return this.headlines[id];
|
||||||
},
|
},
|
||||||
setCommonClasses: function () {
|
setCommonClasses: function () {
|
||||||
$("headlines-frame").removeClassName("cdm");
|
App.byId("headlines-frame").removeClassName("cdm");
|
||||||
$("headlines-frame").removeClassName("normal");
|
App.byId("headlines-frame").removeClassName("normal");
|
||||||
|
|
||||||
$("headlines-frame").addClassName(App.isCombinedMode() ? "cdm" : "normal");
|
App.byId("headlines-frame").addClassName(App.isCombinedMode() ? "cdm" : "normal");
|
||||||
|
|
||||||
// for floating title because it's placed outside of headlines-frame
|
// for floating title because it's placed outside of headlines-frame
|
||||||
$("main").removeClassName("expandable");
|
App.byId("main").removeClassName("expandable");
|
||||||
$("main").removeClassName("expanded");
|
App.byId("main").removeClassName("expanded");
|
||||||
|
|
||||||
if (App.isCombinedMode())
|
if (App.isCombinedMode())
|
||||||
$("main").addClassName(App.getInitParam("cdm_expanded") ? " expanded" : " expandable");
|
App.byId("main").addClassName(App.getInitParam("cdm_expanded") ? " expanded" : " expandable");
|
||||||
},
|
},
|
||||||
renderAgain: function () {
|
renderAgain: function () {
|
||||||
// TODO: wrap headline elements into a knockoutjs model to prevent all this stuff
|
// TODO: wrap headline elements into a knockoutjs model to prevent all this stuff
|
||||||
Headlines.setCommonClasses();
|
Headlines.setCommonClasses();
|
||||||
|
|
||||||
$$("#headlines-frame > div[id*=RROW]").each((row) => {
|
App.findAll("#headlines-frame > div[id*=RROW]").forEach((row) => {
|
||||||
const id = row.getAttribute("data-article-id");
|
const id = row.getAttribute("data-article-id");
|
||||||
const hl = this.headlines[id];
|
const hl = this.headlines[id];
|
||||||
|
|
||||||
|
@ -401,12 +401,12 @@ const Headlines = {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
$$(".cdm .header-sticky-guard").each((e) => {
|
App.findAll(".cdm .header-sticky-guard").forEach((e) => {
|
||||||
this.sticky_header_observer.observe(e)
|
this.sticky_header_observer.observe(e)
|
||||||
});
|
});
|
||||||
|
|
||||||
if (App.getInitParam("cdm_expanded"))
|
if (App.getInitParam("cdm_expanded"))
|
||||||
$$("#headlines-frame > div[id*=RROW].cdm").each((e) => {
|
App.findAll("#headlines-frame > div[id*=RROW].cdm").forEach((e) => {
|
||||||
this.unpack_observer.observe(e)
|
this.unpack_observer.observe(e)
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -431,7 +431,7 @@ const Headlines = {
|
||||||
const tmp = document.createElement("div");
|
const tmp = document.createElement("div");
|
||||||
tmp.innerHTML = vgrhdr;
|
tmp.innerHTML = vgrhdr;
|
||||||
|
|
||||||
$("headlines-frame").appendChild(tmp.firstChild);
|
App.byId("headlines-frame").appendChild(tmp.firstChild);
|
||||||
|
|
||||||
this.vgroup_last_feed = hl.feed_id;
|
this.vgroup_last_feed = hl.feed_id;
|
||||||
}
|
}
|
||||||
|
@ -555,11 +555,11 @@ const Headlines = {
|
||||||
return tmp.firstChild;
|
return tmp.firstChild;
|
||||||
},
|
},
|
||||||
updateCurrentUnread: function () {
|
updateCurrentUnread: function () {
|
||||||
if ($("feed_current_unread")) {
|
if (App.byId("feed_current_unread")) {
|
||||||
const feed_unread = Feeds.getUnread(Feeds.getActive(), Feeds.activeIsCat());
|
const feed_unread = Feeds.getUnread(Feeds.getActive(), Feeds.activeIsCat());
|
||||||
|
|
||||||
if (feed_unread > 0 && !Element.visible("feeds-holder")) {
|
if (feed_unread > 0 && !Element.visible("feeds-holder")) {
|
||||||
$("feed_current_unread").innerText = feed_unread;
|
App.byId("feed_current_unread").innerText = feed_unread;
|
||||||
Element.show("feed_current_unread");
|
Element.show("feed_current_unread");
|
||||||
} else {
|
} else {
|
||||||
Element.hide("feed_current_unread");
|
Element.hide("feed_current_unread");
|
||||||
|
@ -653,15 +653,15 @@ const Headlines = {
|
||||||
// also called in renderAgain() after view mode switch
|
// also called in renderAgain() after view mode switch
|
||||||
Headlines.setCommonClasses();
|
Headlines.setCommonClasses();
|
||||||
|
|
||||||
$("headlines-frame").setAttribute("is-vfeed",
|
App.byId("headlines-frame").setAttribute("is-vfeed",
|
||||||
reply['headlines']['is_vfeed'] ? 1 : 0);
|
reply['headlines']['is_vfeed'] ? 1 : 0);
|
||||||
|
|
||||||
Article.setActive(0);
|
Article.setActive(0);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
$("headlines-frame").removeClassName("smooth-scroll");
|
App.byId("headlines-frame").removeClassName("smooth-scroll");
|
||||||
$("headlines-frame").scrollTop = 0;
|
App.byId("headlines-frame").scrollTop = 0;
|
||||||
$("headlines-frame").addClassName("smooth-scroll");
|
App.byId("headlines-frame").addClassName("smooth-scroll");
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.warn(e);
|
console.warn(e);
|
||||||
}
|
}
|
||||||
|
@ -669,27 +669,27 @@ const Headlines = {
|
||||||
this.headlines = [];
|
this.headlines = [];
|
||||||
this.vgroup_last_feed = undefined;
|
this.vgroup_last_feed = undefined;
|
||||||
|
|
||||||
/*dojo.html.set($("toolbar-headlines"),
|
/*dojo.html.set(App.byId("toolbar-headlines"),
|
||||||
reply['headlines']['toolbar'],
|
reply['headlines']['toolbar'],
|
||||||
{parseContent: true});*/
|
{parseContent: true});*/
|
||||||
|
|
||||||
Headlines.renderToolbar(reply['headlines']);
|
Headlines.renderToolbar(reply['headlines']);
|
||||||
|
|
||||||
if (typeof reply['headlines']['content'] == 'string') {
|
if (typeof reply['headlines']['content'] == 'string') {
|
||||||
$("headlines-frame").innerHTML = reply['headlines']['content'];
|
App.byId("headlines-frame").innerHTML = reply['headlines']['content'];
|
||||||
} else {
|
} else {
|
||||||
$("headlines-frame").innerHTML = '';
|
App.byId("headlines-frame").innerHTML = '';
|
||||||
|
|
||||||
for (let i = 0; i < reply['headlines']['content'].length; i++) {
|
for (let i = 0; i < reply['headlines']['content'].length; i++) {
|
||||||
const hl = reply['headlines']['content'][i];
|
const hl = reply['headlines']['content'][i];
|
||||||
|
|
||||||
$("headlines-frame").appendChild(this.render(reply['headlines'], hl));
|
App.byId("headlines-frame").appendChild(this.render(reply['headlines'], hl));
|
||||||
|
|
||||||
this.headlines[parseInt(hl.id)] = hl;
|
this.headlines[parseInt(hl.id)] = hl;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let hsp = $("headlines-spacer");
|
let hsp = App.byId("headlines-spacer");
|
||||||
|
|
||||||
if (!hsp) {
|
if (!hsp) {
|
||||||
hsp = document.createElement("div");
|
hsp = document.createElement("div");
|
||||||
|
@ -706,7 +706,7 @@ const Headlines = {
|
||||||
|
|
||||||
/*
|
/*
|
||||||
if (Feeds._search_query) {
|
if (Feeds._search_query) {
|
||||||
$("feed_title").innerHTML += "<span id='cancel_search'>" +
|
App.byId("feed_title").innerHTML += "<span id='cancel_search'>" +
|
||||||
" (<a href='#' onclick='Feeds.cancelSearch()'>" + __("Cancel search") + "</a>)" +
|
" (<a href='#' onclick='Feeds.cancelSearch()'>" + __("Cancel search") + "</a>)" +
|
||||||
"</span>";
|
"</span>";
|
||||||
} */
|
} */
|
||||||
|
@ -716,7 +716,7 @@ const Headlines = {
|
||||||
} else if (headlines_count > 0 && feed_id == Feeds.getActive() && is_cat == Feeds.activeIsCat()) {
|
} else if (headlines_count > 0 && feed_id == Feeds.getActive() && is_cat == Feeds.activeIsCat()) {
|
||||||
const c = dijit.byId("headlines-frame");
|
const c = dijit.byId("headlines-frame");
|
||||||
|
|
||||||
let hsp = $("headlines-spacer");
|
let hsp = App.byId("headlines-spacer");
|
||||||
|
|
||||||
if (hsp)
|
if (hsp)
|
||||||
c.domNode.removeChild(hsp);
|
c.domNode.removeChild(hsp);
|
||||||
|
@ -724,13 +724,13 @@ const Headlines = {
|
||||||
let headlines_appended = 0;
|
let headlines_appended = 0;
|
||||||
|
|
||||||
if (typeof reply['headlines']['content'] == 'string') {
|
if (typeof reply['headlines']['content'] == 'string') {
|
||||||
$("headlines-frame").innerHTML = reply['headlines']['content'];
|
App.byId("headlines-frame").innerHTML = reply['headlines']['content'];
|
||||||
} else {
|
} else {
|
||||||
for (let i = 0; i < reply['headlines']['content'].length; i++) {
|
for (let i = 0; i < reply['headlines']['content'].length; i++) {
|
||||||
const hl = reply['headlines']['content'][i];
|
const hl = reply['headlines']['content'][i];
|
||||||
|
|
||||||
if (!this.headlines[parseInt(hl.id)]) {
|
if (!this.headlines[parseInt(hl.id)]) {
|
||||||
$("headlines-frame").appendChild(this.render(reply['headlines'], hl));
|
App.byId("headlines-frame").appendChild(this.render(reply['headlines'], hl));
|
||||||
|
|
||||||
this.headlines[parseInt(hl.id)] = hl;
|
this.headlines[parseInt(hl.id)] = hl;
|
||||||
++headlines_appended;
|
++headlines_appended;
|
||||||
|
@ -762,7 +762,7 @@ const Headlines = {
|
||||||
|
|
||||||
console.log("no headlines received, infscroll_disabled=", Feeds.infscroll_disabled, 'first_id_changed=', first_id_changed);
|
console.log("no headlines received, infscroll_disabled=", Feeds.infscroll_disabled, 'first_id_changed=', first_id_changed);
|
||||||
|
|
||||||
const hsp = $("headlines-spacer");
|
const hsp = App.byId("headlines-spacer");
|
||||||
|
|
||||||
if (hsp) {
|
if (hsp) {
|
||||||
if (first_id_changed) {
|
if (first_id_changed) {
|
||||||
|
@ -775,12 +775,12 @@ const Headlines = {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
$$(".cdm .header-sticky-guard").each((e) => {
|
App.findAll(".cdm .header-sticky-guard").forEach((e) => {
|
||||||
this.sticky_header_observer.observe(e)
|
this.sticky_header_observer.observe(e)
|
||||||
});
|
});
|
||||||
|
|
||||||
if (App.getInitParam("cdm_expanded"))
|
if (App.getInitParam("cdm_expanded"))
|
||||||
$$("#headlines-frame > div[id*=RROW].cdm").each((e) => {
|
App.findAll("#headlines-frame > div[id*=RROW].cdm").forEach((e) => {
|
||||||
this.unpack_observer.observe(e)
|
this.unpack_observer.observe(e)
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -826,8 +826,8 @@ const Headlines = {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
ids.each((id) => {
|
ids.forEach((id) => {
|
||||||
const row = $("RROW-" + id);
|
const row = App.byId("RROW-" + id);
|
||||||
|
|
||||||
if (row) {
|
if (row) {
|
||||||
switch (cmode) {
|
switch (cmode) {
|
||||||
|
@ -851,7 +851,7 @@ const Headlines = {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
ids.each((id) => {
|
ids.forEach((id) => {
|
||||||
this.toggleMark(id);
|
this.toggleMark(id);
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
@ -863,19 +863,19 @@ const Headlines = {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
ids.each((id) => {
|
ids.forEach((id) => {
|
||||||
this.togglePub(id);
|
this.togglePub(id);
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
toggleMark: function (id) {
|
toggleMark: function (id) {
|
||||||
const row = $("RROW-" + id);
|
const row = App.byId("RROW-" + id);
|
||||||
|
|
||||||
if (row)
|
if (row)
|
||||||
row.toggleClassName("marked");
|
row.toggleClassName("marked");
|
||||||
|
|
||||||
},
|
},
|
||||||
togglePub: function (id) {
|
togglePub: function (id) {
|
||||||
const row = $("RROW-" + id);
|
const row = App.byId("RROW-" + id);
|
||||||
|
|
||||||
if (row)
|
if (row)
|
||||||
row.toggleClassName("published");
|
row.toggleClassName("published");
|
||||||
|
@ -889,7 +889,7 @@ const Headlines = {
|
||||||
let next_id = false;
|
let next_id = false;
|
||||||
let current_id = Article.getActive();
|
let current_id = Article.getActive();
|
||||||
|
|
||||||
if (!Headlines.isChildVisible($("RROW-" + current_id))) {
|
if (!Headlines.isChildVisible(App.byId("RROW-" + current_id))) {
|
||||||
console.log('active article is obscured, resetting to first visible...');
|
console.log('active article is obscured, resetting to first visible...');
|
||||||
current_id = Headlines.firstVisible();
|
current_id = Headlines.firstVisible();
|
||||||
prev_id = current_id;
|
prev_id = current_id;
|
||||||
|
@ -928,15 +928,15 @@ const Headlines = {
|
||||||
}
|
}
|
||||||
} else if (App.isCombinedMode()) {
|
} else if (App.isCombinedMode()) {
|
||||||
// try to show hsp if no next article exists, in case there's useful information like first_id_changed etc
|
// try to show hsp if no next article exists, in case there's useful information like first_id_changed etc
|
||||||
const row = $("RROW-" + current_id);
|
const row = App.byId("RROW-" + current_id);
|
||||||
const ctr = $("headlines-frame");
|
const ctr = App.byId("headlines-frame");
|
||||||
|
|
||||||
if (row) {
|
if (row) {
|
||||||
const next = row.nextSibling;
|
const next = row.nextSibling;
|
||||||
|
|
||||||
// hsp has half-screen height in auto catchup mode therefore we use its first child (normally A element)
|
// hsp has half-screen height in auto catchup mode therefore we use its first child (normally A element)
|
||||||
if (next && Element.visible(next) && next.id == "headlines-spacer" && next.firstChild) {
|
if (next && Element.visible(next) && next.id == "headlines-spacer" && next.firstChild) {
|
||||||
const offset = $("headlines-spacer").offsetTop - $("headlines-frame").offsetHeight + next.firstChild.offsetHeight;
|
const offset = App.byId("headlines-spacer").offsetTop - App.byId("headlines-frame").offsetHeight + next.firstChild.offsetHeight;
|
||||||
|
|
||||||
// don't jump back either
|
// don't jump back either
|
||||||
if (ctr.scrollTop < offset)
|
if (ctr.scrollTop < offset)
|
||||||
|
@ -948,8 +948,8 @@ const Headlines = {
|
||||||
if (prev_id || current_id) {
|
if (prev_id || current_id) {
|
||||||
if (App.isCombinedMode()) {
|
if (App.isCombinedMode()) {
|
||||||
window.requestAnimationFrame(() => {
|
window.requestAnimationFrame(() => {
|
||||||
const row = $("RROW-" + current_id);
|
const row = App.byId("RROW-" + current_id);
|
||||||
const ctr = $("headlines-frame");
|
const ctr = App.byId("headlines-frame");
|
||||||
const delta_px = Math.round(row.offsetTop) - Math.round(ctr.scrollTop);
|
const delta_px = Math.round(row.offsetTop) - Math.round(ctr.scrollTop);
|
||||||
|
|
||||||
console.log('moving back, delta_px', delta_px);
|
console.log('moving back, delta_px', delta_px);
|
||||||
|
@ -970,7 +970,7 @@ const Headlines = {
|
||||||
},
|
},
|
||||||
updateSelectedPrompt: function () {
|
updateSelectedPrompt: function () {
|
||||||
const count = Headlines.getSelected().length;
|
const count = Headlines.getSelected().length;
|
||||||
const elem = $("selected_prompt");
|
const elem = App.byId("selected_prompt");
|
||||||
|
|
||||||
if (elem) {
|
if (elem) {
|
||||||
elem.innerHTML = ngettext("%d article selected",
|
elem.innerHTML = ngettext("%d article selected",
|
||||||
|
@ -980,7 +980,7 @@ const Headlines = {
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
toggleUnread: function (id, cmode) {
|
toggleUnread: function (id, cmode) {
|
||||||
const row = $("RROW-" + id);
|
const row = App.byId("RROW-" + id);
|
||||||
|
|
||||||
if (row) {
|
if (row) {
|
||||||
if (typeof cmode == "undefined") cmode = 2;
|
if (typeof cmode == "undefined") cmode = 2;
|
||||||
|
@ -1068,7 +1068,7 @@ const Headlines = {
|
||||||
getSelected: function () {
|
getSelected: function () {
|
||||||
const rv = [];
|
const rv = [];
|
||||||
|
|
||||||
$$("#headlines-frame > div[id*=RROW][class*=Selected]").each(
|
App.findAll("#headlines-frame > div[id*=RROW][class*=Selected]").forEach(
|
||||||
function (child) {
|
function (child) {
|
||||||
rv.push(child.getAttribute("data-article-id"));
|
rv.push(child.getAttribute("data-article-id"));
|
||||||
});
|
});
|
||||||
|
@ -1082,9 +1082,9 @@ const Headlines = {
|
||||||
getLoaded: function () {
|
getLoaded: function () {
|
||||||
const rv = [];
|
const rv = [];
|
||||||
|
|
||||||
const children = $$("#headlines-frame > div[id*=RROW-]");
|
const children = App.findAll("#headlines-frame > div[id*=RROW-]");
|
||||||
|
|
||||||
children.each(function (child) {
|
children.forEach(function (child) {
|
||||||
if (Element.visible(child)) {
|
if (Element.visible(child)) {
|
||||||
rv.push(child.getAttribute("data-article-id"));
|
rv.push(child.getAttribute("data-article-id"));
|
||||||
}
|
}
|
||||||
|
@ -1111,7 +1111,7 @@ const Headlines = {
|
||||||
if (start == stop)
|
if (start == stop)
|
||||||
return [start];
|
return [start];
|
||||||
|
|
||||||
const rows = $$("#headlines-frame > div[id*=RROW]");
|
const rows = App.findAll("#headlines-frame > div[id*=RROW]");
|
||||||
const results = [];
|
const results = [];
|
||||||
let collecting = false;
|
let collecting = false;
|
||||||
|
|
||||||
|
@ -1158,10 +1158,7 @@ const Headlines = {
|
||||||
console.warn("select: unknown mode", mode);
|
console.warn("select: unknown mode", mode);
|
||||||
}
|
}
|
||||||
|
|
||||||
const rows = $$(query);
|
App.findAll(query).forEach((row) => {
|
||||||
|
|
||||||
for (let i = 0; i < rows.length; i++) {
|
|
||||||
const row = rows[i];
|
|
||||||
|
|
||||||
switch (mode) {
|
switch (mode) {
|
||||||
case "none":
|
case "none":
|
||||||
|
@ -1173,7 +1170,7 @@ const Headlines = {
|
||||||
default:
|
default:
|
||||||
row.addClassName("Selected");
|
row.addClassName("Selected");
|
||||||
}
|
}
|
||||||
}
|
});
|
||||||
},
|
},
|
||||||
catchupSelection: function () {
|
catchupSelection: function () {
|
||||||
const rows = Headlines.getSelected();
|
const rows = Headlines.getSelected();
|
||||||
|
@ -1212,7 +1209,7 @@ const Headlines = {
|
||||||
if (!below) {
|
if (!below) {
|
||||||
for (let i = 0; i < visible_ids.length; i++) {
|
for (let i = 0; i < visible_ids.length; i++) {
|
||||||
if (visible_ids[i] != id) {
|
if (visible_ids[i] != id) {
|
||||||
const e = $("RROW-" + visible_ids[i]);
|
const e = App.byId("RROW-" + visible_ids[i]);
|
||||||
|
|
||||||
if (e && e.hasClassName("Unread")) {
|
if (e && e.hasClassName("Unread")) {
|
||||||
ids_to_mark.push(visible_ids[i]);
|
ids_to_mark.push(visible_ids[i]);
|
||||||
|
@ -1224,7 +1221,7 @@ const Headlines = {
|
||||||
} else {
|
} else {
|
||||||
for (let i = visible_ids.length - 1; i >= 0; i--) {
|
for (let i = visible_ids.length - 1; i >= 0; i--) {
|
||||||
if (visible_ids[i] != id) {
|
if (visible_ids[i] != id) {
|
||||||
const e = $("RROW-" + visible_ids[i]);
|
const e = App.byId("RROW-" + visible_ids[i]);
|
||||||
|
|
||||||
if (e && e.hasClassName("Unread")) {
|
if (e && e.hasClassName("Unread")) {
|
||||||
ids_to_mark.push(visible_ids[i]);
|
ids_to_mark.push(visible_ids[i]);
|
||||||
|
@ -1243,7 +1240,7 @@ const Headlines = {
|
||||||
if (App.getInitParam("confirm_feed_catchup") != 1 || confirm(msg)) {
|
if (App.getInitParam("confirm_feed_catchup") != 1 || confirm(msg)) {
|
||||||
|
|
||||||
for (let i = 0; i < ids_to_mark.length; i++) {
|
for (let i = 0; i < ids_to_mark.length; i++) {
|
||||||
const e = $("RROW-" + ids_to_mark[i]);
|
const e = App.byId("RROW-" + ids_to_mark[i]);
|
||||||
e.removeClassName("Unread");
|
e.removeClassName("Unread");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1253,16 +1250,16 @@ const Headlines = {
|
||||||
const data = JSON.parse(transport.responseText);
|
const data = JSON.parse(transport.responseText);
|
||||||
|
|
||||||
if (data) {
|
if (data) {
|
||||||
data['info-for-headlines'].each(function (elem) {
|
data['info-for-headlines'].forEach(function (elem) {
|
||||||
$$(".HLLCTR-" + elem.id).each(function (ctr) {
|
App.findAll(".HLLCTR-" + elem.id).forEach(function (ctr) {
|
||||||
ctr.innerHTML = elem.labels;
|
ctr.innerHTML = elem.labels;
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
scrollToArticleId: function (id) {
|
scrollToArticleId: function (id) {
|
||||||
const container = $("headlines-frame");
|
const container = App.byId("headlines-frame");
|
||||||
const row = $("RROW-" + id);
|
const row = App.byId("RROW-" + id);
|
||||||
|
|
||||||
if (!container || !row) return;
|
if (!container || !row) return;
|
||||||
|
|
||||||
|
@ -1361,7 +1358,7 @@ const Headlines = {
|
||||||
const labelAddMenu = new dijit.Menu({ownerMenu: menu});
|
const labelAddMenu = new dijit.Menu({ownerMenu: menu});
|
||||||
const labelDelMenu = new dijit.Menu({ownerMenu: menu});
|
const labelDelMenu = new dijit.Menu({ownerMenu: menu});
|
||||||
|
|
||||||
labels.each(function (label) {
|
labels.forEach(function (label) {
|
||||||
const bare_id = label.id;
|
const bare_id = label.id;
|
||||||
const name = label.caption;
|
const name = label.caption;
|
||||||
|
|
||||||
|
@ -1409,10 +1406,10 @@ const Headlines = {
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
scrollByPages: function (page_offset) {
|
scrollByPages: function (page_offset) {
|
||||||
App.Scrollable.scrollByPages($("headlines-frame"), page_offset);
|
App.Scrollable.scrollByPages(App.byId("headlines-frame"), page_offset);
|
||||||
},
|
},
|
||||||
scroll: function (offset) {
|
scroll: function (offset) {
|
||||||
App.Scrollable.scroll($("headlines-frame"), offset);
|
App.Scrollable.scroll(App.byId("headlines-frame"), offset);
|
||||||
},
|
},
|
||||||
initHeadlinesMenu: function () {
|
initHeadlinesMenu: function () {
|
||||||
if (!dijit.byId("headlinesMenu")) {
|
if (!dijit.byId("headlinesMenu")) {
|
||||||
|
|
|
@ -126,7 +126,7 @@ define(["dojo/_base/declare", "dojo/dom-construct", "lib/CheckBoxTree", "dojo/_b
|
||||||
return (!item || this.model.store.getValue(item, 'type') == 'category') ? (opened ? "dijitFolderOpened" : "dijitFolderClosed") : "feed-icon";
|
return (!item || this.model.store.getValue(item, 'type') == 'category') ? (opened ? "dijitFolderOpened" : "dijitFolderClosed") : "feed-icon";
|
||||||
},
|
},
|
||||||
reload: function() {
|
reload: function() {
|
||||||
const searchElem = $("feed_search");
|
const searchElem = App.byId("feed_search");
|
||||||
const search = (searchElem) ? searchElem.value : "";
|
const search = (searchElem) ? searchElem.value : "";
|
||||||
|
|
||||||
xhrPost("backend.php", { op: "pref-feeds", search: search }, (transport) => {
|
xhrPost("backend.php", { op: "pref-feeds", search: search }, (transport) => {
|
||||||
|
@ -228,7 +228,7 @@ define(["dojo/_base/declare", "dojo/dom-construct", "lib/CheckBoxTree", "dojo/_b
|
||||||
const items = tree.model.getCheckedItems();
|
const items = tree.model.getCheckedItems();
|
||||||
const rv = [];
|
const rv = [];
|
||||||
|
|
||||||
items.each(function (item) {
|
items.forEach(function (item) {
|
||||||
if (item.id[0].match("CAT:"))
|
if (item.id[0].match("CAT:"))
|
||||||
rv.push(tree.model.store.getValue(item, 'bare_id'));
|
rv.push(tree.model.store.getValue(item, 'bare_id'));
|
||||||
});
|
});
|
||||||
|
@ -262,7 +262,7 @@ define(["dojo/_base/declare", "dojo/dom-construct", "lib/CheckBoxTree", "dojo/_b
|
||||||
const items = tree.model.getCheckedItems();
|
const items = tree.model.getCheckedItems();
|
||||||
const rv = [];
|
const rv = [];
|
||||||
|
|
||||||
items.each(function (item) {
|
items.forEach(function (item) {
|
||||||
if (item.id[0].match("FEED:"))
|
if (item.id[0].match("FEED:"))
|
||||||
rv.push(tree.model.store.getValue(item, 'bare_id'));
|
rv.push(tree.model.store.getValue(item, 'bare_id'));
|
||||||
});
|
});
|
||||||
|
@ -304,7 +304,7 @@ define(["dojo/_base/declare", "dojo/dom-construct", "lib/CheckBoxTree", "dojo/_b
|
||||||
title: __("Edit Multiple Feeds"),
|
title: __("Edit Multiple Feeds"),
|
||||||
getChildByName: function (name) {
|
getChildByName: function (name) {
|
||||||
let rv = null;
|
let rv = null;
|
||||||
this.getChildren().each(
|
this.getChildren().forEach(
|
||||||
function (child) {
|
function (child) {
|
||||||
if (child.name == name) {
|
if (child.name == name) {
|
||||||
rv = child;
|
rv = child;
|
||||||
|
@ -329,7 +329,7 @@ define(["dojo/_base/declare", "dojo/dom-construct", "lib/CheckBoxTree", "dojo/_b
|
||||||
|
|
||||||
/* normalize unchecked checkboxes because [] is not serialized */
|
/* normalize unchecked checkboxes because [] is not serialized */
|
||||||
|
|
||||||
Object.keys(query).each((key) => {
|
Object.keys(query).forEach((key) => {
|
||||||
const val = query[key];
|
const val = query[key];
|
||||||
|
|
||||||
if (typeof val == "object" && val.length == 0)
|
if (typeof val == "object" && val.length == 0)
|
||||||
|
|
|
@ -80,14 +80,14 @@ define(["dojo/_base/declare", "dojo/dom-construct", "lib/CheckBoxTree"], functio
|
||||||
const items = tree.model.getCheckedItems();
|
const items = tree.model.getCheckedItems();
|
||||||
const rv = [];
|
const rv = [];
|
||||||
|
|
||||||
items.each(function (item) {
|
items.forEach(function (item) {
|
||||||
rv.push(tree.model.store.getValue(item, 'bare_id'));
|
rv.push(tree.model.store.getValue(item, 'bare_id'));
|
||||||
});
|
});
|
||||||
|
|
||||||
return rv;
|
return rv;
|
||||||
},
|
},
|
||||||
reload: function() {
|
reload: function() {
|
||||||
const user_search = $("filter_search");
|
const user_search = App.byId("filter_search");
|
||||||
let search = "";
|
let search = "";
|
||||||
if (user_search) { search = user_search.value; }
|
if (user_search) { search = user_search.value; }
|
||||||
|
|
||||||
|
|
|
@ -9,7 +9,7 @@ const Helpers = {
|
||||||
return Tables.getSelected("app-password-list");
|
return Tables.getSelected("app-password-list");
|
||||||
},
|
},
|
||||||
updateContent: function(data) {
|
updateContent: function(data) {
|
||||||
$("app_passwords_holder").innerHTML = data;
|
App.byId("app_passwords_holder").innerHTML = data;
|
||||||
dojo.parser.parse("app_passwords_holder");
|
dojo.parser.parse("app_passwords_holder");
|
||||||
},
|
},
|
||||||
removeSelected: function() {
|
removeSelected: function() {
|
||||||
|
@ -218,8 +218,8 @@ const Helpers = {
|
||||||
title: __("Customize stylesheet"),
|
title: __("Customize stylesheet"),
|
||||||
apply: function() {
|
apply: function() {
|
||||||
xhrPost("backend.php", this.attr('value'), () => {
|
xhrPost("backend.php", this.attr('value'), () => {
|
||||||
new Effect.Appear("css_edit_apply_msg");
|
Element.show("css_edit_apply_msg");
|
||||||
$("user_css_style").innerText = this.attr('value');
|
App.byId("user_css_style").innerText = this.attr('value');
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
execute: function () {
|
execute: function () {
|
||||||
|
@ -291,7 +291,7 @@ const Helpers = {
|
||||||
},
|
},
|
||||||
OPML: {
|
OPML: {
|
||||||
import: function() {
|
import: function() {
|
||||||
const opml_file = $("opml_file");
|
const opml_file = App.byId("opml_file");
|
||||||
|
|
||||||
if (opml_file.value.length == 0) {
|
if (opml_file.value.length == 0) {
|
||||||
alert(__("Please choose an OPML file first."));
|
alert(__("Please choose an OPML file first."));
|
||||||
|
@ -333,7 +333,7 @@ const Helpers = {
|
||||||
dialog.show();
|
dialog.show();
|
||||||
};
|
};
|
||||||
|
|
||||||
xhr.send(new FormData($("opml_import_form")));
|
xhr.send(new FormData(App.byId("opml_import_form")));
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
|
@ -48,7 +48,7 @@ define(["dojo/_base/declare", "dojo/dom-construct", "lib/CheckBoxTree", "dijit/f
|
||||||
const items = tree.model.getCheckedItems();
|
const items = tree.model.getCheckedItems();
|
||||||
const rv = [];
|
const rv = [];
|
||||||
|
|
||||||
items.each(function(item) {
|
items.forEach(function(item) {
|
||||||
rv.push(tree.model.store.getValue(item, 'bare_id'));
|
rv.push(tree.model.store.getValue(item, 'bare_id'));
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -87,7 +87,7 @@ define(["dojo/_base/declare", "dojo/dom-construct", "lib/CheckBoxTree", "dijit/f
|
||||||
color = bg;
|
color = bg;
|
||||||
}
|
}
|
||||||
|
|
||||||
const e = $("icon-label-" + id);
|
const e = App.byId("icon-label-" + id);
|
||||||
|
|
||||||
if (e) {
|
if (e) {
|
||||||
if (bg) e.style.color = bg;
|
if (bg) e.style.color = bg;
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
|
|
||||||
const Users = {
|
const Users = {
|
||||||
reload: function(sort) {
|
reload: function(sort) {
|
||||||
const user_search = $("user_search");
|
const user_search = App.byId("user_search");
|
||||||
const search = user_search ? user_search.value : "";
|
const search = user_search ? user_search.value : "";
|
||||||
|
|
||||||
xhrPost("backend.php", { op: "pref-users", sort: sort, search: search }, (transport) => {
|
xhrPost("backend.php", { op: "pref-users", sort: sort, search: search }, (transport) => {
|
||||||
|
|
133
js/common.js
133
js/common.js
|
@ -3,35 +3,117 @@
|
||||||
/* global dijit, __, App, Ajax */
|
/* global dijit, __, App, Ajax */
|
||||||
/* eslint-disable no-new */
|
/* eslint-disable no-new */
|
||||||
|
|
||||||
/* error reporting shim */
|
Element.prototype.hasClassName = function(className) {
|
||||||
// TODO: deprecated; remove
|
dojo.hasClass(this, className);
|
||||||
/* function exception_error(e, e_compat, filename, lineno, colno) {
|
};
|
||||||
if (typeof e == "string")
|
|
||||||
e = e_compat;
|
|
||||||
|
|
||||||
App.Error.report(e, {filename: filename, lineno: lineno, colno: colno});
|
Element.prototype.addClassName = function(className) {
|
||||||
} */
|
dojo.addClass(this, className);
|
||||||
|
};
|
||||||
|
|
||||||
|
Element.prototype.removeClassName = function(className) {
|
||||||
|
dojo.removeClass(this, className);
|
||||||
|
};
|
||||||
|
|
||||||
|
Element.prototype.setStyle = function(args) {
|
||||||
|
Object.keys(args).forEach((k) => {
|
||||||
|
this.style[k] = args[k];
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
Element.prototype.show = function() {
|
||||||
|
this.style.display = "";
|
||||||
|
};
|
||||||
|
|
||||||
|
Element.prototype.hide = function() {
|
||||||
|
this.style.display = "none";
|
||||||
|
};
|
||||||
|
|
||||||
|
Element.prototype.toggle = function() {
|
||||||
|
if (this.visible())
|
||||||
|
this.show();
|
||||||
|
else
|
||||||
|
this.hide();
|
||||||
|
};
|
||||||
|
|
||||||
|
Element.prototype.visible = function() {
|
||||||
|
// TODO: should we actually check for offsetWidth/offsetHeight == 0?
|
||||||
|
return this.style.display != "none";
|
||||||
|
}
|
||||||
|
|
||||||
|
Element.visible = function(elem) {
|
||||||
|
if (typeof elem == "string")
|
||||||
|
elem = document.getElementById(elem);
|
||||||
|
|
||||||
|
return elem.visible();
|
||||||
|
}
|
||||||
|
|
||||||
|
Element.show = function(elem) {
|
||||||
|
if (typeof elem == "string")
|
||||||
|
elem = document.getElementById(elem);
|
||||||
|
|
||||||
|
return elem.show();
|
||||||
|
}
|
||||||
|
|
||||||
|
Element.hide = function(elem) {
|
||||||
|
if (typeof elem == "string")
|
||||||
|
elem = document.getElementById(elem);
|
||||||
|
|
||||||
|
return elem.hide();
|
||||||
|
}
|
||||||
|
|
||||||
|
Element.toggle = function(elem) {
|
||||||
|
if (typeof elem == "string")
|
||||||
|
elem = document.getElementById(elem);
|
||||||
|
|
||||||
|
return elem.toggle();
|
||||||
|
}
|
||||||
|
|
||||||
|
Element.hasClassName = function (id, className) {
|
||||||
|
return document.getElementById(id).hasClassName(className);
|
||||||
|
}
|
||||||
|
|
||||||
/* xhr shorthand helpers */
|
/* xhr shorthand helpers */
|
||||||
|
|
||||||
/* exported xhrPost */
|
/* exported xhrPost */
|
||||||
function xhrPost(url, params, complete) {
|
function xhrPost(url, params = {}, complete = undefined) {
|
||||||
console.log("xhrPost:", params);
|
console.log("xhrPost:", params);
|
||||||
|
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
new Ajax.Request(url, {
|
if (typeof __csrf_token != "undefined")
|
||||||
parameters: params,
|
params = {...params, ...{csrf_token: __csrf_token}};
|
||||||
onComplete: function(reply) {
|
|
||||||
if (complete != undefined) complete(reply);
|
|
||||||
|
|
||||||
resolve(reply);
|
dojo.xhrPost({url: url,
|
||||||
}
|
postData: dojo.objectToQuery(params),
|
||||||
});
|
handleAs: "text",
|
||||||
|
error: function(error) {
|
||||||
|
reject(error);
|
||||||
|
},
|
||||||
|
load: function(data, ioargs) {
|
||||||
|
if (complete != undefined)
|
||||||
|
complete(ioargs.xhr);
|
||||||
|
|
||||||
|
resolve(ioargs.xhr)
|
||||||
|
}});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Array.prototype.remove = function(s) {
|
||||||
|
for (let i=0; i < this.length; i++) {
|
||||||
|
if (s == this[i]) this.splice(i, 1);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
Array.prototype.uniq = function() {
|
||||||
|
return this.filter((v, i, a) => a.indexOf(v) === i);
|
||||||
|
};
|
||||||
|
|
||||||
|
String.prototype.stripTags = function() {
|
||||||
|
return this.replace(/<\w+(\s+("[^"]*"|'[^']*'|[^>])+)?(\/)?>|<\/\w+>/gi, '');
|
||||||
|
}
|
||||||
|
|
||||||
/* exported xhrJson */
|
/* exported xhrJson */
|
||||||
function xhrJson(url, params, complete) {
|
function xhrJson(url, params = {}, complete = undefined) {
|
||||||
return new Promise((resolve, reject) =>
|
return new Promise((resolve, reject) =>
|
||||||
xhrPost(url, params).then((reply) => {
|
xhrPost(url, params).then((reply) => {
|
||||||
let obj = null;
|
let obj = null;
|
||||||
|
@ -48,13 +130,6 @@ function xhrJson(url, params, complete) {
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
/* add method to remove element from array */
|
|
||||||
Array.prototype.remove = function(s) {
|
|
||||||
for (let i=0; i < this.length; i++) {
|
|
||||||
if (s == this[i]) this.splice(i, 1);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
/* common helpers not worthy of separate Dojo modules */
|
/* common helpers not worthy of separate Dojo modules */
|
||||||
|
|
||||||
/* exported Lists */
|
/* exported Lists */
|
||||||
|
@ -70,8 +145,8 @@ const Lists = {
|
||||||
checked ? row.addClassName("Selected") : row.removeClassName("Selected");
|
checked ? row.addClassName("Selected") : row.removeClassName("Selected");
|
||||||
},
|
},
|
||||||
select: function(elemId, selected) {
|
select: function(elemId, selected) {
|
||||||
$(elemId).select("li").each((row) => {
|
$(elemId).querySelectorAll("li").forEach((row) => {
|
||||||
const checkNode = row.select(".dijitCheckBox,input[type=checkbox]")[0];
|
const checkNode = row.querySelector(".dijitCheckBox,input[type=checkbox]");
|
||||||
if (checkNode) {
|
if (checkNode) {
|
||||||
const widget = dijit.getEnclosingWidget(checkNode);
|
const widget = dijit.getEnclosingWidget(checkNode);
|
||||||
|
|
||||||
|
@ -101,8 +176,8 @@ const Tables = {
|
||||||
|
|
||||||
},
|
},
|
||||||
select: function(elemId, selected) {
|
select: function(elemId, selected) {
|
||||||
$(elemId).select("tr").each((row) => {
|
$(elemId).querySelector("tr").forEach((row) => {
|
||||||
const checkNode = row.select(".dijitCheckBox,input[type=checkbox]")[0];
|
const checkNode = row.querySelector(".dijitCheckBox,input[type=checkbox]");
|
||||||
if (checkNode) {
|
if (checkNode) {
|
||||||
const widget = dijit.getEnclosingWidget(checkNode);
|
const widget = dijit.getEnclosingWidget(checkNode);
|
||||||
|
|
||||||
|
@ -119,7 +194,7 @@ const Tables = {
|
||||||
getSelected: function(elemId) {
|
getSelected: function(elemId) {
|
||||||
const rv = [];
|
const rv = [];
|
||||||
|
|
||||||
$(elemId).select("tr").each((row) => {
|
$(elemId).querySelector("tr").forEach((row) => {
|
||||||
if (row.hasClassName("Selected")) {
|
if (row.hasClassName("Selected")) {
|
||||||
// either older prefix-XXX notation or separate attribute
|
// either older prefix-XXX notation or separate attribute
|
||||||
const rowId = row.getAttribute("data-row-id") || row.id.replace(/^[A-Z]*?-/, "");
|
const rowId = row.getAttribute("data-row-id") || row.id.replace(/^[A-Z]*?-/, "");
|
||||||
|
@ -173,7 +248,7 @@ const Notify = {
|
||||||
kind = kind || this.KIND_GENERIC;
|
kind = kind || this.KIND_GENERIC;
|
||||||
keep = keep || false;
|
keep = keep || false;
|
||||||
|
|
||||||
const notify = $("notify");
|
const notify = App.byId("notify");
|
||||||
|
|
||||||
window.clearTimeout(this.timeout);
|
window.clearTimeout(this.timeout);
|
||||||
|
|
||||||
|
|
15
js/tt-rss.js
15
js/tt-rss.js
|
@ -70,13 +70,20 @@ require(["dojo/_base/kernel",
|
||||||
|
|
||||||
/* exported hash_get */
|
/* exported hash_get */
|
||||||
function hash_get(key) {
|
function hash_get(key) {
|
||||||
const kv = window.location.hash.substring(1).toQueryParams();
|
console.warn("FIXME: hash_get", key);
|
||||||
return kv[key];
|
|
||||||
|
//const kv = window.location.hash.substring(1).toQueryParams();
|
||||||
|
//return kv[key];
|
||||||
|
console.warn("FIXME: hash_get", key);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* exported hash_set */
|
/* exported hash_set */
|
||||||
function hash_set(key, value) {
|
function hash_set(key, value) {
|
||||||
const kv = window.location.hash.substring(1).toQueryParams();
|
console.warn("FIXME: hash_set", key, value);
|
||||||
|
|
||||||
|
/*const kv = window.location.hash.substring(1).toQueryParams();
|
||||||
kv[key] = value;
|
kv[key] = value;
|
||||||
window.location.hash = $H(kv).toQueryString();
|
window.location.hash = $H(kv).toQueryString();*/
|
||||||
|
|
||||||
|
console.warn("FIXME: hash_set", key);
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
|
|
||||||
/* TODO: this should probably be something like night_mode.js since it does nothing specific to utility scripts */
|
/* TODO: this should probably be something like night_mode.js since it does nothing specific to utility scripts */
|
||||||
|
|
||||||
Event.observe(window, "load", function() {
|
window.addEventListener("load", function() {
|
||||||
const UtilityJS = {
|
const UtilityJS = {
|
||||||
apply_night_mode: function (is_night, link) {
|
apply_night_mode: function (is_night, link) {
|
||||||
console.log("night mode changed to", is_night);
|
console.log("night mode changed to", is_night);
|
||||||
|
|
|
@ -1,965 +0,0 @@
|
||||||
// script.aculo.us controls.js v1.9.0, Thu Dec 23 16:54:48 -0500 2010
|
|
||||||
|
|
||||||
// Copyright (c) 2005-2010 Thomas Fuchs (http://script.aculo.us, http://mir.aculo.us)
|
|
||||||
// (c) 2005-2010 Ivan Krstic (http://blogs.law.harvard.edu/ivan)
|
|
||||||
// (c) 2005-2010 Jon Tirsen (http://www.tirsen.com)
|
|
||||||
// Contributors:
|
|
||||||
// Richard Livsey
|
|
||||||
// Rahul Bhargava
|
|
||||||
// Rob Wills
|
|
||||||
//
|
|
||||||
// script.aculo.us is freely distributable under the terms of an MIT-style license.
|
|
||||||
// For details, see the script.aculo.us web site: http://script.aculo.us/
|
|
||||||
|
|
||||||
// Autocompleter.Base handles all the autocompletion functionality
|
|
||||||
// that's independent of the data source for autocompletion. This
|
|
||||||
// includes drawing the autocompletion menu, observing keyboard
|
|
||||||
// and mouse events, and similar.
|
|
||||||
//
|
|
||||||
// Specific autocompleters need to provide, at the very least,
|
|
||||||
// a getUpdatedChoices function that will be invoked every time
|
|
||||||
// the text inside the monitored textbox changes. This method
|
|
||||||
// should get the text for which to provide autocompletion by
|
|
||||||
// invoking this.getToken(), NOT by directly accessing
|
|
||||||
// this.element.value. This is to allow incremental tokenized
|
|
||||||
// autocompletion. Specific auto-completion logic (AJAX, etc)
|
|
||||||
// belongs in getUpdatedChoices.
|
|
||||||
//
|
|
||||||
// Tokenized incremental autocompletion is enabled automatically
|
|
||||||
// when an autocompleter is instantiated with the 'tokens' option
|
|
||||||
// in the options parameter, e.g.:
|
|
||||||
// new Ajax.Autocompleter('id','upd', '/url/', { tokens: ',' });
|
|
||||||
// will incrementally autocomplete with a comma as the token.
|
|
||||||
// Additionally, ',' in the above example can be replaced with
|
|
||||||
// a token array, e.g. { tokens: [',', '\n'] } which
|
|
||||||
// enables autocompletion on multiple tokens. This is most
|
|
||||||
// useful when one of the tokens is \n (a newline), as it
|
|
||||||
// allows smart autocompletion after linebreaks.
|
|
||||||
|
|
||||||
if(typeof Effect == 'undefined')
|
|
||||||
throw("controls.js requires including script.aculo.us' effects.js library");
|
|
||||||
|
|
||||||
var Autocompleter = { };
|
|
||||||
Autocompleter.Base = Class.create({
|
|
||||||
baseInitialize: function(element, update, options) {
|
|
||||||
element = $(element);
|
|
||||||
this.element = element;
|
|
||||||
this.update = $(update);
|
|
||||||
this.hasFocus = false;
|
|
||||||
this.changed = false;
|
|
||||||
this.active = false;
|
|
||||||
this.index = 0;
|
|
||||||
this.entryCount = 0;
|
|
||||||
this.oldElementValue = this.element.value;
|
|
||||||
|
|
||||||
if(this.setOptions)
|
|
||||||
this.setOptions(options);
|
|
||||||
else
|
|
||||||
this.options = options || { };
|
|
||||||
|
|
||||||
this.options.paramName = this.options.paramName || this.element.name;
|
|
||||||
this.options.tokens = this.options.tokens || [];
|
|
||||||
this.options.frequency = this.options.frequency || 0.4;
|
|
||||||
this.options.minChars = this.options.minChars || 1;
|
|
||||||
this.options.onShow = this.options.onShow ||
|
|
||||||
function(element, update){
|
|
||||||
if(!update.style.position || update.style.position=='absolute') {
|
|
||||||
update.style.position = 'absolute';
|
|
||||||
Position.clone(element, update, {
|
|
||||||
setHeight: false,
|
|
||||||
offsetTop: element.offsetHeight
|
|
||||||
});
|
|
||||||
}
|
|
||||||
Effect.Appear(update,{duration:0.15});
|
|
||||||
};
|
|
||||||
this.options.onHide = this.options.onHide ||
|
|
||||||
function(element, update){ new Effect.Fade(update,{duration:0.15}) };
|
|
||||||
|
|
||||||
if(typeof(this.options.tokens) == 'string')
|
|
||||||
this.options.tokens = new Array(this.options.tokens);
|
|
||||||
// Force carriage returns as token delimiters anyway
|
|
||||||
if (!this.options.tokens.include('\n'))
|
|
||||||
this.options.tokens.push('\n');
|
|
||||||
|
|
||||||
this.observer = null;
|
|
||||||
|
|
||||||
this.element.setAttribute('autocomplete','off');
|
|
||||||
|
|
||||||
Element.hide(this.update);
|
|
||||||
|
|
||||||
Event.observe(this.element, 'blur', this.onBlur.bindAsEventListener(this));
|
|
||||||
Event.observe(this.element, 'keydown', this.onKeyPress.bindAsEventListener(this));
|
|
||||||
},
|
|
||||||
|
|
||||||
show: function() {
|
|
||||||
if(Element.getStyle(this.update, 'display')=='none') this.options.onShow(this.element, this.update);
|
|
||||||
if(!this.iefix &&
|
|
||||||
(Prototype.Browser.IE) &&
|
|
||||||
(Element.getStyle(this.update, 'position')=='absolute')) {
|
|
||||||
new Insertion.After(this.update,
|
|
||||||
'<iframe id="' + this.update.id + '_iefix" '+
|
|
||||||
'style="display:none;position:absolute;filter:progid:DXImageTransform.Microsoft.Alpha(opacity=0);" ' +
|
|
||||||
'src="javascript:false;" frameborder="0" scrolling="no"></iframe>');
|
|
||||||
this.iefix = $(this.update.id+'_iefix');
|
|
||||||
}
|
|
||||||
if(this.iefix) setTimeout(this.fixIEOverlapping.bind(this), 50);
|
|
||||||
},
|
|
||||||
|
|
||||||
fixIEOverlapping: function() {
|
|
||||||
Position.clone(this.update, this.iefix, {setTop:(!this.update.style.height)});
|
|
||||||
this.iefix.style.zIndex = 1;
|
|
||||||
this.update.style.zIndex = 2;
|
|
||||||
Element.show(this.iefix);
|
|
||||||
},
|
|
||||||
|
|
||||||
hide: function() {
|
|
||||||
this.stopIndicator();
|
|
||||||
if(Element.getStyle(this.update, 'display')!='none') this.options.onHide(this.element, this.update);
|
|
||||||
if(this.iefix) Element.hide(this.iefix);
|
|
||||||
},
|
|
||||||
|
|
||||||
startIndicator: function() {
|
|
||||||
if(this.options.indicator) Element.show(this.options.indicator);
|
|
||||||
},
|
|
||||||
|
|
||||||
stopIndicator: function() {
|
|
||||||
if(this.options.indicator) Element.hide(this.options.indicator);
|
|
||||||
},
|
|
||||||
|
|
||||||
onKeyPress: function(event) {
|
|
||||||
if(this.active)
|
|
||||||
switch(event.keyCode) {
|
|
||||||
case Event.KEY_TAB:
|
|
||||||
case Event.KEY_RETURN:
|
|
||||||
this.selectEntry();
|
|
||||||
Event.stop(event);
|
|
||||||
case Event.KEY_ESC:
|
|
||||||
this.hide();
|
|
||||||
this.active = false;
|
|
||||||
Event.stop(event);
|
|
||||||
return;
|
|
||||||
case Event.KEY_LEFT:
|
|
||||||
case Event.KEY_RIGHT:
|
|
||||||
return;
|
|
||||||
case Event.KEY_UP:
|
|
||||||
this.markPrevious();
|
|
||||||
this.render();
|
|
||||||
Event.stop(event);
|
|
||||||
return;
|
|
||||||
case Event.KEY_DOWN:
|
|
||||||
this.markNext();
|
|
||||||
this.render();
|
|
||||||
Event.stop(event);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
if(event.keyCode==Event.KEY_TAB || event.keyCode==Event.KEY_RETURN ||
|
|
||||||
(Prototype.Browser.WebKit > 0 && event.keyCode == 0)) return;
|
|
||||||
|
|
||||||
this.changed = true;
|
|
||||||
this.hasFocus = true;
|
|
||||||
|
|
||||||
if(this.observer) clearTimeout(this.observer);
|
|
||||||
this.observer =
|
|
||||||
setTimeout(this.onObserverEvent.bind(this), this.options.frequency*1000);
|
|
||||||
},
|
|
||||||
|
|
||||||
activate: function() {
|
|
||||||
this.changed = false;
|
|
||||||
this.hasFocus = true;
|
|
||||||
this.getUpdatedChoices();
|
|
||||||
},
|
|
||||||
|
|
||||||
onHover: function(event) {
|
|
||||||
var element = Event.findElement(event, 'LI');
|
|
||||||
if(this.index != element.autocompleteIndex)
|
|
||||||
{
|
|
||||||
this.index = element.autocompleteIndex;
|
|
||||||
this.render();
|
|
||||||
}
|
|
||||||
Event.stop(event);
|
|
||||||
},
|
|
||||||
|
|
||||||
onClick: function(event) {
|
|
||||||
var element = Event.findElement(event, 'LI');
|
|
||||||
this.index = element.autocompleteIndex;
|
|
||||||
this.selectEntry();
|
|
||||||
this.hide();
|
|
||||||
},
|
|
||||||
|
|
||||||
onBlur: function(event) {
|
|
||||||
// needed to make click events working
|
|
||||||
setTimeout(this.hide.bind(this), 250);
|
|
||||||
this.hasFocus = false;
|
|
||||||
this.active = false;
|
|
||||||
},
|
|
||||||
|
|
||||||
render: function() {
|
|
||||||
if(this.entryCount > 0) {
|
|
||||||
for (var i = 0; i < this.entryCount; i++)
|
|
||||||
this.index==i ?
|
|
||||||
Element.addClassName(this.getEntry(i),"selected") :
|
|
||||||
Element.removeClassName(this.getEntry(i),"selected");
|
|
||||||
if(this.hasFocus) {
|
|
||||||
this.show();
|
|
||||||
this.active = true;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
this.active = false;
|
|
||||||
this.hide();
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
markPrevious: function() {
|
|
||||||
if(this.index > 0) this.index--;
|
|
||||||
else this.index = this.entryCount-1;
|
|
||||||
this.getEntry(this.index).scrollIntoView(true);
|
|
||||||
},
|
|
||||||
|
|
||||||
markNext: function() {
|
|
||||||
if(this.index < this.entryCount-1) this.index++;
|
|
||||||
else this.index = 0;
|
|
||||||
this.getEntry(this.index).scrollIntoView(false);
|
|
||||||
},
|
|
||||||
|
|
||||||
getEntry: function(index) {
|
|
||||||
return this.update.firstChild.childNodes[index];
|
|
||||||
},
|
|
||||||
|
|
||||||
getCurrentEntry: function() {
|
|
||||||
return this.getEntry(this.index);
|
|
||||||
},
|
|
||||||
|
|
||||||
selectEntry: function() {
|
|
||||||
this.active = false;
|
|
||||||
this.updateElement(this.getCurrentEntry());
|
|
||||||
},
|
|
||||||
|
|
||||||
updateElement: function(selectedElement) {
|
|
||||||
if (this.options.updateElement) {
|
|
||||||
this.options.updateElement(selectedElement);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
var value = '';
|
|
||||||
if (this.options.select) {
|
|
||||||
var nodes = $(selectedElement).select('.' + this.options.select) || [];
|
|
||||||
if(nodes.length>0) value = Element.collectTextNodes(nodes[0], this.options.select);
|
|
||||||
} else
|
|
||||||
value = Element.collectTextNodesIgnoreClass(selectedElement, 'informal');
|
|
||||||
|
|
||||||
var bounds = this.getTokenBounds();
|
|
||||||
if (bounds[0] != -1) {
|
|
||||||
var newValue = this.element.value.substr(0, bounds[0]);
|
|
||||||
var whitespace = this.element.value.substr(bounds[0]).match(/^\s+/);
|
|
||||||
if (whitespace)
|
|
||||||
newValue += whitespace[0];
|
|
||||||
this.element.value = newValue + value + this.element.value.substr(bounds[1]);
|
|
||||||
} else {
|
|
||||||
this.element.value = value;
|
|
||||||
}
|
|
||||||
this.oldElementValue = this.element.value;
|
|
||||||
this.element.focus();
|
|
||||||
|
|
||||||
if (this.options.afterUpdateElement)
|
|
||||||
this.options.afterUpdateElement(this.element, selectedElement);
|
|
||||||
},
|
|
||||||
|
|
||||||
updateChoices: function(choices) {
|
|
||||||
if(!this.changed && this.hasFocus) {
|
|
||||||
this.update.innerHTML = choices;
|
|
||||||
Element.cleanWhitespace(this.update);
|
|
||||||
Element.cleanWhitespace(this.update.down());
|
|
||||||
|
|
||||||
if(this.update.firstChild && this.update.down().childNodes) {
|
|
||||||
this.entryCount =
|
|
||||||
this.update.down().childNodes.length;
|
|
||||||
for (var i = 0; i < this.entryCount; i++) {
|
|
||||||
var entry = this.getEntry(i);
|
|
||||||
entry.autocompleteIndex = i;
|
|
||||||
this.addObservers(entry);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
this.entryCount = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
this.stopIndicator();
|
|
||||||
this.index = 0;
|
|
||||||
|
|
||||||
if(this.entryCount==1 && this.options.autoSelect) {
|
|
||||||
this.selectEntry();
|
|
||||||
this.hide();
|
|
||||||
} else {
|
|
||||||
this.render();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
addObservers: function(element) {
|
|
||||||
Event.observe(element, "mouseover", this.onHover.bindAsEventListener(this));
|
|
||||||
Event.observe(element, "click", this.onClick.bindAsEventListener(this));
|
|
||||||
},
|
|
||||||
|
|
||||||
onObserverEvent: function() {
|
|
||||||
this.changed = false;
|
|
||||||
this.tokenBounds = null;
|
|
||||||
if(this.getToken().length>=this.options.minChars) {
|
|
||||||
this.getUpdatedChoices();
|
|
||||||
} else {
|
|
||||||
this.active = false;
|
|
||||||
this.hide();
|
|
||||||
}
|
|
||||||
this.oldElementValue = this.element.value;
|
|
||||||
},
|
|
||||||
|
|
||||||
getToken: function() {
|
|
||||||
var bounds = this.getTokenBounds();
|
|
||||||
return this.element.value.substring(bounds[0], bounds[1]).strip();
|
|
||||||
},
|
|
||||||
|
|
||||||
getTokenBounds: function() {
|
|
||||||
if (null != this.tokenBounds) return this.tokenBounds;
|
|
||||||
var value = this.element.value;
|
|
||||||
if (value.strip().empty()) return [-1, 0];
|
|
||||||
var diff = arguments.callee.getFirstDifferencePos(value, this.oldElementValue);
|
|
||||||
var offset = (diff == this.oldElementValue.length ? 1 : 0);
|
|
||||||
var prevTokenPos = -1, nextTokenPos = value.length;
|
|
||||||
var tp;
|
|
||||||
for (var index = 0, l = this.options.tokens.length; index < l; ++index) {
|
|
||||||
tp = value.lastIndexOf(this.options.tokens[index], diff + offset - 1);
|
|
||||||
if (tp > prevTokenPos) prevTokenPos = tp;
|
|
||||||
tp = value.indexOf(this.options.tokens[index], diff + offset);
|
|
||||||
if (-1 != tp && tp < nextTokenPos) nextTokenPos = tp;
|
|
||||||
}
|
|
||||||
return (this.tokenBounds = [prevTokenPos + 1, nextTokenPos]);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
Autocompleter.Base.prototype.getTokenBounds.getFirstDifferencePos = function(newS, oldS) {
|
|
||||||
var boundary = Math.min(newS.length, oldS.length);
|
|
||||||
for (var index = 0; index < boundary; ++index)
|
|
||||||
if (newS[index] != oldS[index])
|
|
||||||
return index;
|
|
||||||
return boundary;
|
|
||||||
};
|
|
||||||
|
|
||||||
Ajax.Autocompleter = Class.create(Autocompleter.Base, {
|
|
||||||
initialize: function(element, update, url, options) {
|
|
||||||
this.baseInitialize(element, update, options);
|
|
||||||
this.options.asynchronous = true;
|
|
||||||
this.options.onComplete = this.onComplete.bind(this);
|
|
||||||
this.options.defaultParams = this.options.parameters || null;
|
|
||||||
this.url = url;
|
|
||||||
},
|
|
||||||
|
|
||||||
getUpdatedChoices: function() {
|
|
||||||
this.startIndicator();
|
|
||||||
|
|
||||||
var entry = encodeURIComponent(this.options.paramName) + '=' +
|
|
||||||
encodeURIComponent(this.getToken());
|
|
||||||
|
|
||||||
this.options.parameters = this.options.callback ?
|
|
||||||
this.options.callback(this.element, entry) : entry;
|
|
||||||
|
|
||||||
if(this.options.defaultParams)
|
|
||||||
this.options.parameters += '&' + this.options.defaultParams;
|
|
||||||
|
|
||||||
new Ajax.Request(this.url, this.options);
|
|
||||||
},
|
|
||||||
|
|
||||||
onComplete: function(request) {
|
|
||||||
this.updateChoices(request.responseText);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
// The local array autocompleter. Used when you'd prefer to
|
|
||||||
// inject an array of autocompletion options into the page, rather
|
|
||||||
// than sending out Ajax queries, which can be quite slow sometimes.
|
|
||||||
//
|
|
||||||
// The constructor takes four parameters. The first two are, as usual,
|
|
||||||
// the id of the monitored textbox, and id of the autocompletion menu.
|
|
||||||
// The third is the array you want to autocomplete from, and the fourth
|
|
||||||
// is the options block.
|
|
||||||
//
|
|
||||||
// Extra local autocompletion options:
|
|
||||||
// - choices - How many autocompletion choices to offer
|
|
||||||
//
|
|
||||||
// - partialSearch - If false, the autocompleter will match entered
|
|
||||||
// text only at the beginning of strings in the
|
|
||||||
// autocomplete array. Defaults to true, which will
|
|
||||||
// match text at the beginning of any *word* in the
|
|
||||||
// strings in the autocomplete array. If you want to
|
|
||||||
// search anywhere in the string, additionally set
|
|
||||||
// the option fullSearch to true (default: off).
|
|
||||||
//
|
|
||||||
// - fullSsearch - Search anywhere in autocomplete array strings.
|
|
||||||
//
|
|
||||||
// - partialChars - How many characters to enter before triggering
|
|
||||||
// a partial match (unlike minChars, which defines
|
|
||||||
// how many characters are required to do any match
|
|
||||||
// at all). Defaults to 2.
|
|
||||||
//
|
|
||||||
// - ignoreCase - Whether to ignore case when autocompleting.
|
|
||||||
// Defaults to true.
|
|
||||||
//
|
|
||||||
// It's possible to pass in a custom function as the 'selector'
|
|
||||||
// option, if you prefer to write your own autocompletion logic.
|
|
||||||
// In that case, the other options above will not apply unless
|
|
||||||
// you support them.
|
|
||||||
|
|
||||||
Autocompleter.Local = Class.create(Autocompleter.Base, {
|
|
||||||
initialize: function(element, update, array, options) {
|
|
||||||
this.baseInitialize(element, update, options);
|
|
||||||
this.options.array = array;
|
|
||||||
},
|
|
||||||
|
|
||||||
getUpdatedChoices: function() {
|
|
||||||
this.updateChoices(this.options.selector(this));
|
|
||||||
},
|
|
||||||
|
|
||||||
setOptions: function(options) {
|
|
||||||
this.options = Object.extend({
|
|
||||||
choices: 10,
|
|
||||||
partialSearch: true,
|
|
||||||
partialChars: 2,
|
|
||||||
ignoreCase: true,
|
|
||||||
fullSearch: false,
|
|
||||||
selector: function(instance) {
|
|
||||||
var ret = []; // Beginning matches
|
|
||||||
var partial = []; // Inside matches
|
|
||||||
var entry = instance.getToken();
|
|
||||||
var count = 0;
|
|
||||||
|
|
||||||
for (var i = 0; i < instance.options.array.length &&
|
|
||||||
ret.length < instance.options.choices ; i++) {
|
|
||||||
|
|
||||||
var elem = instance.options.array[i];
|
|
||||||
var foundPos = instance.options.ignoreCase ?
|
|
||||||
elem.toLowerCase().indexOf(entry.toLowerCase()) :
|
|
||||||
elem.indexOf(entry);
|
|
||||||
|
|
||||||
while (foundPos != -1) {
|
|
||||||
if (foundPos == 0 && elem.length != entry.length) {
|
|
||||||
ret.push("<li><strong>" + elem.substr(0, entry.length) + "</strong>" +
|
|
||||||
elem.substr(entry.length) + "</li>");
|
|
||||||
break;
|
|
||||||
} else if (entry.length >= instance.options.partialChars &&
|
|
||||||
instance.options.partialSearch && foundPos != -1) {
|
|
||||||
if (instance.options.fullSearch || /\s/.test(elem.substr(foundPos-1,1))) {
|
|
||||||
partial.push("<li>" + elem.substr(0, foundPos) + "<strong>" +
|
|
||||||
elem.substr(foundPos, entry.length) + "</strong>" + elem.substr(
|
|
||||||
foundPos + entry.length) + "</li>");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
foundPos = instance.options.ignoreCase ?
|
|
||||||
elem.toLowerCase().indexOf(entry.toLowerCase(), foundPos + 1) :
|
|
||||||
elem.indexOf(entry, foundPos + 1);
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (partial.length)
|
|
||||||
ret = ret.concat(partial.slice(0, instance.options.choices - ret.length));
|
|
||||||
return "<ul>" + ret.join('') + "</ul>";
|
|
||||||
}
|
|
||||||
}, options || { });
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
// AJAX in-place editor and collection editor
|
|
||||||
// Full rewrite by Christophe Porteneuve <tdd@tddsworld.com> (April 2007).
|
|
||||||
|
|
||||||
// Use this if you notice weird scrolling problems on some browsers,
|
|
||||||
// the DOM might be a bit confused when this gets called so do this
|
|
||||||
// waits 1 ms (with setTimeout) until it does the activation
|
|
||||||
Field.scrollFreeActivate = function(field) {
|
|
||||||
setTimeout(function() {
|
|
||||||
Field.activate(field);
|
|
||||||
}, 1);
|
|
||||||
};
|
|
||||||
|
|
||||||
Ajax.InPlaceEditor = Class.create({
|
|
||||||
initialize: function(element, url, options) {
|
|
||||||
this.url = url;
|
|
||||||
this.element = element = $(element);
|
|
||||||
this.prepareOptions();
|
|
||||||
this._controls = { };
|
|
||||||
arguments.callee.dealWithDeprecatedOptions(options); // DEPRECATION LAYER!!!
|
|
||||||
Object.extend(this.options, options || { });
|
|
||||||
if (!this.options.formId && this.element.id) {
|
|
||||||
this.options.formId = this.element.id + '-inplaceeditor';
|
|
||||||
if ($(this.options.formId))
|
|
||||||
this.options.formId = '';
|
|
||||||
}
|
|
||||||
if (this.options.externalControl)
|
|
||||||
this.options.externalControl = $(this.options.externalControl);
|
|
||||||
if (!this.options.externalControl)
|
|
||||||
this.options.externalControlOnly = false;
|
|
||||||
this._originalBackground = this.element.getStyle('background-color') || 'transparent';
|
|
||||||
this.element.title = this.options.clickToEditText;
|
|
||||||
this._boundCancelHandler = this.handleFormCancellation.bind(this);
|
|
||||||
this._boundComplete = (this.options.onComplete || Prototype.emptyFunction).bind(this);
|
|
||||||
this._boundFailureHandler = this.handleAJAXFailure.bind(this);
|
|
||||||
this._boundSubmitHandler = this.handleFormSubmission.bind(this);
|
|
||||||
this._boundWrapperHandler = this.wrapUp.bind(this);
|
|
||||||
this.registerListeners();
|
|
||||||
},
|
|
||||||
checkForEscapeOrReturn: function(e) {
|
|
||||||
if (!this._editing || e.ctrlKey || e.altKey || e.shiftKey) return;
|
|
||||||
if (Event.KEY_ESC == e.keyCode)
|
|
||||||
this.handleFormCancellation(e);
|
|
||||||
else if (Event.KEY_RETURN == e.keyCode)
|
|
||||||
this.handleFormSubmission(e);
|
|
||||||
},
|
|
||||||
createControl: function(mode, handler, extraClasses) {
|
|
||||||
var control = this.options[mode + 'Control'];
|
|
||||||
var text = this.options[mode + 'Text'];
|
|
||||||
if ('button' == control) {
|
|
||||||
var btn = document.createElement('input');
|
|
||||||
btn.type = 'submit';
|
|
||||||
btn.value = text;
|
|
||||||
btn.className = 'editor_' + mode + '_button';
|
|
||||||
if ('cancel' == mode)
|
|
||||||
btn.onclick = this._boundCancelHandler;
|
|
||||||
this._form.appendChild(btn);
|
|
||||||
this._controls[mode] = btn;
|
|
||||||
} else if ('link' == control) {
|
|
||||||
var link = document.createElement('a');
|
|
||||||
link.href = '#';
|
|
||||||
link.appendChild(document.createTextNode(text));
|
|
||||||
link.onclick = 'cancel' == mode ? this._boundCancelHandler : this._boundSubmitHandler;
|
|
||||||
link.className = 'editor_' + mode + '_link';
|
|
||||||
if (extraClasses)
|
|
||||||
link.className += ' ' + extraClasses;
|
|
||||||
this._form.appendChild(link);
|
|
||||||
this._controls[mode] = link;
|
|
||||||
}
|
|
||||||
},
|
|
||||||
createEditField: function() {
|
|
||||||
var text = (this.options.loadTextURL ? this.options.loadingText : this.getText());
|
|
||||||
var fld;
|
|
||||||
if (1 >= this.options.rows && !/\r|\n/.test(this.getText())) {
|
|
||||||
fld = document.createElement('input');
|
|
||||||
fld.type = 'text';
|
|
||||||
var size = this.options.size || this.options.cols || 0;
|
|
||||||
if (0 < size) fld.size = size;
|
|
||||||
} else {
|
|
||||||
fld = document.createElement('textarea');
|
|
||||||
fld.rows = (1 >= this.options.rows ? this.options.autoRows : this.options.rows);
|
|
||||||
fld.cols = this.options.cols || 40;
|
|
||||||
}
|
|
||||||
fld.name = this.options.paramName;
|
|
||||||
fld.value = text; // No HTML breaks conversion anymore
|
|
||||||
fld.className = 'editor_field';
|
|
||||||
if (this.options.submitOnBlur)
|
|
||||||
fld.onblur = this._boundSubmitHandler;
|
|
||||||
this._controls.editor = fld;
|
|
||||||
if (this.options.loadTextURL)
|
|
||||||
this.loadExternalText();
|
|
||||||
this._form.appendChild(this._controls.editor);
|
|
||||||
},
|
|
||||||
createForm: function() {
|
|
||||||
var ipe = this;
|
|
||||||
function addText(mode, condition) {
|
|
||||||
var text = ipe.options['text' + mode + 'Controls'];
|
|
||||||
if (!text || condition === false) return;
|
|
||||||
ipe._form.appendChild(document.createTextNode(text));
|
|
||||||
};
|
|
||||||
this._form = $(document.createElement('form'));
|
|
||||||
this._form.id = this.options.formId;
|
|
||||||
this._form.addClassName(this.options.formClassName);
|
|
||||||
this._form.onsubmit = this._boundSubmitHandler;
|
|
||||||
this.createEditField();
|
|
||||||
if ('textarea' == this._controls.editor.tagName.toLowerCase())
|
|
||||||
this._form.appendChild(document.createElement('br'));
|
|
||||||
if (this.options.onFormCustomization)
|
|
||||||
this.options.onFormCustomization(this, this._form);
|
|
||||||
addText('Before', this.options.okControl || this.options.cancelControl);
|
|
||||||
this.createControl('ok', this._boundSubmitHandler);
|
|
||||||
addText('Between', this.options.okControl && this.options.cancelControl);
|
|
||||||
this.createControl('cancel', this._boundCancelHandler, 'editor_cancel');
|
|
||||||
addText('After', this.options.okControl || this.options.cancelControl);
|
|
||||||
},
|
|
||||||
destroy: function() {
|
|
||||||
if (this._oldInnerHTML)
|
|
||||||
this.element.innerHTML = this._oldInnerHTML;
|
|
||||||
this.leaveEditMode();
|
|
||||||
this.unregisterListeners();
|
|
||||||
},
|
|
||||||
enterEditMode: function(e) {
|
|
||||||
if (this._saving || this._editing) return;
|
|
||||||
this._editing = true;
|
|
||||||
this.triggerCallback('onEnterEditMode');
|
|
||||||
if (this.options.externalControl)
|
|
||||||
this.options.externalControl.hide();
|
|
||||||
this.element.hide();
|
|
||||||
this.createForm();
|
|
||||||
this.element.parentNode.insertBefore(this._form, this.element);
|
|
||||||
if (!this.options.loadTextURL)
|
|
||||||
this.postProcessEditField();
|
|
||||||
if (e) Event.stop(e);
|
|
||||||
},
|
|
||||||
enterHover: function(e) {
|
|
||||||
if (this.options.hoverClassName)
|
|
||||||
this.element.addClassName(this.options.hoverClassName);
|
|
||||||
if (this._saving) return;
|
|
||||||
this.triggerCallback('onEnterHover');
|
|
||||||
},
|
|
||||||
getText: function() {
|
|
||||||
return this.element.innerHTML.unescapeHTML();
|
|
||||||
},
|
|
||||||
handleAJAXFailure: function(transport) {
|
|
||||||
this.triggerCallback('onFailure', transport);
|
|
||||||
if (this._oldInnerHTML) {
|
|
||||||
this.element.innerHTML = this._oldInnerHTML;
|
|
||||||
this._oldInnerHTML = null;
|
|
||||||
}
|
|
||||||
},
|
|
||||||
handleFormCancellation: function(e) {
|
|
||||||
this.wrapUp();
|
|
||||||
if (e) Event.stop(e);
|
|
||||||
},
|
|
||||||
handleFormSubmission: function(e) {
|
|
||||||
var form = this._form;
|
|
||||||
var value = $F(this._controls.editor);
|
|
||||||
this.prepareSubmission();
|
|
||||||
var params = this.options.callback(form, value) || '';
|
|
||||||
if (Object.isString(params))
|
|
||||||
params = params.toQueryParams();
|
|
||||||
params.editorId = this.element.id;
|
|
||||||
if (this.options.htmlResponse) {
|
|
||||||
var options = Object.extend({ evalScripts: true }, this.options.ajaxOptions);
|
|
||||||
Object.extend(options, {
|
|
||||||
parameters: params,
|
|
||||||
onComplete: this._boundWrapperHandler,
|
|
||||||
onFailure: this._boundFailureHandler
|
|
||||||
});
|
|
||||||
new Ajax.Updater({ success: this.element }, this.url, options);
|
|
||||||
} else {
|
|
||||||
var options = Object.extend({ method: 'get' }, this.options.ajaxOptions);
|
|
||||||
Object.extend(options, {
|
|
||||||
parameters: params,
|
|
||||||
onComplete: this._boundWrapperHandler,
|
|
||||||
onFailure: this._boundFailureHandler
|
|
||||||
});
|
|
||||||
new Ajax.Request(this.url, options);
|
|
||||||
}
|
|
||||||
if (e) Event.stop(e);
|
|
||||||
},
|
|
||||||
leaveEditMode: function() {
|
|
||||||
this.element.removeClassName(this.options.savingClassName);
|
|
||||||
this.removeForm();
|
|
||||||
this.leaveHover();
|
|
||||||
this.element.style.backgroundColor = this._originalBackground;
|
|
||||||
this.element.show();
|
|
||||||
if (this.options.externalControl)
|
|
||||||
this.options.externalControl.show();
|
|
||||||
this._saving = false;
|
|
||||||
this._editing = false;
|
|
||||||
this._oldInnerHTML = null;
|
|
||||||
this.triggerCallback('onLeaveEditMode');
|
|
||||||
},
|
|
||||||
leaveHover: function(e) {
|
|
||||||
if (this.options.hoverClassName)
|
|
||||||
this.element.removeClassName(this.options.hoverClassName);
|
|
||||||
if (this._saving) return;
|
|
||||||
this.triggerCallback('onLeaveHover');
|
|
||||||
},
|
|
||||||
loadExternalText: function() {
|
|
||||||
this._form.addClassName(this.options.loadingClassName);
|
|
||||||
this._controls.editor.disabled = true;
|
|
||||||
var options = Object.extend({ method: 'get' }, this.options.ajaxOptions);
|
|
||||||
Object.extend(options, {
|
|
||||||
parameters: 'editorId=' + encodeURIComponent(this.element.id),
|
|
||||||
onComplete: Prototype.emptyFunction,
|
|
||||||
onSuccess: function(transport) {
|
|
||||||
this._form.removeClassName(this.options.loadingClassName);
|
|
||||||
var text = transport.responseText;
|
|
||||||
if (this.options.stripLoadedTextTags)
|
|
||||||
text = text.stripTags();
|
|
||||||
this._controls.editor.value = text;
|
|
||||||
this._controls.editor.disabled = false;
|
|
||||||
this.postProcessEditField();
|
|
||||||
}.bind(this),
|
|
||||||
onFailure: this._boundFailureHandler
|
|
||||||
});
|
|
||||||
new Ajax.Request(this.options.loadTextURL, options);
|
|
||||||
},
|
|
||||||
postProcessEditField: function() {
|
|
||||||
var fpc = this.options.fieldPostCreation;
|
|
||||||
if (fpc)
|
|
||||||
$(this._controls.editor)['focus' == fpc ? 'focus' : 'activate']();
|
|
||||||
},
|
|
||||||
prepareOptions: function() {
|
|
||||||
this.options = Object.clone(Ajax.InPlaceEditor.DefaultOptions);
|
|
||||||
Object.extend(this.options, Ajax.InPlaceEditor.DefaultCallbacks);
|
|
||||||
[this._extraDefaultOptions].flatten().compact().each(function(defs) {
|
|
||||||
Object.extend(this.options, defs);
|
|
||||||
}.bind(this));
|
|
||||||
},
|
|
||||||
prepareSubmission: function() {
|
|
||||||
this._saving = true;
|
|
||||||
this.removeForm();
|
|
||||||
this.leaveHover();
|
|
||||||
this.showSaving();
|
|
||||||
},
|
|
||||||
registerListeners: function() {
|
|
||||||
this._listeners = { };
|
|
||||||
var listener;
|
|
||||||
$H(Ajax.InPlaceEditor.Listeners).each(function(pair) {
|
|
||||||
listener = this[pair.value].bind(this);
|
|
||||||
this._listeners[pair.key] = listener;
|
|
||||||
if (!this.options.externalControlOnly)
|
|
||||||
this.element.observe(pair.key, listener);
|
|
||||||
if (this.options.externalControl)
|
|
||||||
this.options.externalControl.observe(pair.key, listener);
|
|
||||||
}.bind(this));
|
|
||||||
},
|
|
||||||
removeForm: function() {
|
|
||||||
if (!this._form) return;
|
|
||||||
this._form.remove();
|
|
||||||
this._form = null;
|
|
||||||
this._controls = { };
|
|
||||||
},
|
|
||||||
showSaving: function() {
|
|
||||||
this._oldInnerHTML = this.element.innerHTML;
|
|
||||||
this.element.innerHTML = this.options.savingText;
|
|
||||||
this.element.addClassName(this.options.savingClassName);
|
|
||||||
this.element.style.backgroundColor = this._originalBackground;
|
|
||||||
this.element.show();
|
|
||||||
},
|
|
||||||
triggerCallback: function(cbName, arg) {
|
|
||||||
if ('function' == typeof this.options[cbName]) {
|
|
||||||
this.options[cbName](this, arg);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
unregisterListeners: function() {
|
|
||||||
$H(this._listeners).each(function(pair) {
|
|
||||||
if (!this.options.externalControlOnly)
|
|
||||||
this.element.stopObserving(pair.key, pair.value);
|
|
||||||
if (this.options.externalControl)
|
|
||||||
this.options.externalControl.stopObserving(pair.key, pair.value);
|
|
||||||
}.bind(this));
|
|
||||||
},
|
|
||||||
wrapUp: function(transport) {
|
|
||||||
this.leaveEditMode();
|
|
||||||
// Can't use triggerCallback due to backward compatibility: requires
|
|
||||||
// binding + direct element
|
|
||||||
this._boundComplete(transport, this.element);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
Object.extend(Ajax.InPlaceEditor.prototype, {
|
|
||||||
dispose: Ajax.InPlaceEditor.prototype.destroy
|
|
||||||
});
|
|
||||||
|
|
||||||
Ajax.InPlaceCollectionEditor = Class.create(Ajax.InPlaceEditor, {
|
|
||||||
initialize: function($super, element, url, options) {
|
|
||||||
this._extraDefaultOptions = Ajax.InPlaceCollectionEditor.DefaultOptions;
|
|
||||||
$super(element, url, options);
|
|
||||||
},
|
|
||||||
|
|
||||||
createEditField: function() {
|
|
||||||
var list = document.createElement('select');
|
|
||||||
list.name = this.options.paramName;
|
|
||||||
list.size = 1;
|
|
||||||
this._controls.editor = list;
|
|
||||||
this._collection = this.options.collection || [];
|
|
||||||
if (this.options.loadCollectionURL)
|
|
||||||
this.loadCollection();
|
|
||||||
else
|
|
||||||
this.checkForExternalText();
|
|
||||||
this._form.appendChild(this._controls.editor);
|
|
||||||
},
|
|
||||||
|
|
||||||
loadCollection: function() {
|
|
||||||
this._form.addClassName(this.options.loadingClassName);
|
|
||||||
this.showLoadingText(this.options.loadingCollectionText);
|
|
||||||
var options = Object.extend({ method: 'get' }, this.options.ajaxOptions);
|
|
||||||
Object.extend(options, {
|
|
||||||
parameters: 'editorId=' + encodeURIComponent(this.element.id),
|
|
||||||
onComplete: Prototype.emptyFunction,
|
|
||||||
onSuccess: function(transport) {
|
|
||||||
var js = transport.responseText.strip();
|
|
||||||
if (!/^\[.*\]$/.test(js)) // TODO: improve sanity check
|
|
||||||
throw('Server returned an invalid collection representation.');
|
|
||||||
this._collection = eval(js);
|
|
||||||
this.checkForExternalText();
|
|
||||||
}.bind(this),
|
|
||||||
onFailure: this.onFailure
|
|
||||||
});
|
|
||||||
new Ajax.Request(this.options.loadCollectionURL, options);
|
|
||||||
},
|
|
||||||
|
|
||||||
showLoadingText: function(text) {
|
|
||||||
this._controls.editor.disabled = true;
|
|
||||||
var tempOption = this._controls.editor.firstChild;
|
|
||||||
if (!tempOption) {
|
|
||||||
tempOption = document.createElement('option');
|
|
||||||
tempOption.value = '';
|
|
||||||
this._controls.editor.appendChild(tempOption);
|
|
||||||
tempOption.selected = true;
|
|
||||||
}
|
|
||||||
tempOption.update((text || '').stripScripts().stripTags());
|
|
||||||
},
|
|
||||||
|
|
||||||
checkForExternalText: function() {
|
|
||||||
this._text = this.getText();
|
|
||||||
if (this.options.loadTextURL)
|
|
||||||
this.loadExternalText();
|
|
||||||
else
|
|
||||||
this.buildOptionList();
|
|
||||||
},
|
|
||||||
|
|
||||||
loadExternalText: function() {
|
|
||||||
this.showLoadingText(this.options.loadingText);
|
|
||||||
var options = Object.extend({ method: 'get' }, this.options.ajaxOptions);
|
|
||||||
Object.extend(options, {
|
|
||||||
parameters: 'editorId=' + encodeURIComponent(this.element.id),
|
|
||||||
onComplete: Prototype.emptyFunction,
|
|
||||||
onSuccess: function(transport) {
|
|
||||||
this._text = transport.responseText.strip();
|
|
||||||
this.buildOptionList();
|
|
||||||
}.bind(this),
|
|
||||||
onFailure: this.onFailure
|
|
||||||
});
|
|
||||||
new Ajax.Request(this.options.loadTextURL, options);
|
|
||||||
},
|
|
||||||
|
|
||||||
buildOptionList: function() {
|
|
||||||
this._form.removeClassName(this.options.loadingClassName);
|
|
||||||
this._collection = this._collection.map(function(entry) {
|
|
||||||
return 2 === entry.length ? entry : [entry, entry].flatten();
|
|
||||||
});
|
|
||||||
var marker = ('value' in this.options) ? this.options.value : this._text;
|
|
||||||
var textFound = this._collection.any(function(entry) {
|
|
||||||
return entry[0] == marker;
|
|
||||||
}.bind(this));
|
|
||||||
this._controls.editor.update('');
|
|
||||||
var option;
|
|
||||||
this._collection.each(function(entry, index) {
|
|
||||||
option = document.createElement('option');
|
|
||||||
option.value = entry[0];
|
|
||||||
option.selected = textFound ? entry[0] == marker : 0 == index;
|
|
||||||
option.appendChild(document.createTextNode(entry[1]));
|
|
||||||
this._controls.editor.appendChild(option);
|
|
||||||
}.bind(this));
|
|
||||||
this._controls.editor.disabled = false;
|
|
||||||
Field.scrollFreeActivate(this._controls.editor);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
//**** DEPRECATION LAYER FOR InPlace[Collection]Editor! ****
|
|
||||||
//**** This only exists for a while, in order to let ****
|
|
||||||
//**** users adapt to the new API. Read up on the new ****
|
|
||||||
//**** API and convert your code to it ASAP! ****
|
|
||||||
|
|
||||||
Ajax.InPlaceEditor.prototype.initialize.dealWithDeprecatedOptions = function(options) {
|
|
||||||
if (!options) return;
|
|
||||||
function fallback(name, expr) {
|
|
||||||
if (name in options || expr === undefined) return;
|
|
||||||
options[name] = expr;
|
|
||||||
};
|
|
||||||
fallback('cancelControl', (options.cancelLink ? 'link' : (options.cancelButton ? 'button' :
|
|
||||||
options.cancelLink == options.cancelButton == false ? false : undefined)));
|
|
||||||
fallback('okControl', (options.okLink ? 'link' : (options.okButton ? 'button' :
|
|
||||||
options.okLink == options.okButton == false ? false : undefined)));
|
|
||||||
fallback('highlightColor', options.highlightcolor);
|
|
||||||
fallback('highlightEndColor', options.highlightendcolor);
|
|
||||||
};
|
|
||||||
|
|
||||||
Object.extend(Ajax.InPlaceEditor, {
|
|
||||||
DefaultOptions: {
|
|
||||||
ajaxOptions: { },
|
|
||||||
autoRows: 3, // Use when multi-line w/ rows == 1
|
|
||||||
cancelControl: 'link', // 'link'|'button'|false
|
|
||||||
cancelText: 'cancel',
|
|
||||||
clickToEditText: 'Click to edit',
|
|
||||||
externalControl: null, // id|elt
|
|
||||||
externalControlOnly: false,
|
|
||||||
fieldPostCreation: 'activate', // 'activate'|'focus'|false
|
|
||||||
formClassName: 'inplaceeditor-form',
|
|
||||||
formId: null, // id|elt
|
|
||||||
highlightColor: '#ffff99',
|
|
||||||
highlightEndColor: '#ffffff',
|
|
||||||
hoverClassName: '',
|
|
||||||
htmlResponse: true,
|
|
||||||
loadingClassName: 'inplaceeditor-loading',
|
|
||||||
loadingText: 'Loading...',
|
|
||||||
okControl: 'button', // 'link'|'button'|false
|
|
||||||
okText: 'ok',
|
|
||||||
paramName: 'value',
|
|
||||||
rows: 1, // If 1 and multi-line, uses autoRows
|
|
||||||
savingClassName: 'inplaceeditor-saving',
|
|
||||||
savingText: 'Saving...',
|
|
||||||
size: 0,
|
|
||||||
stripLoadedTextTags: false,
|
|
||||||
submitOnBlur: false,
|
|
||||||
textAfterControls: '',
|
|
||||||
textBeforeControls: '',
|
|
||||||
textBetweenControls: ''
|
|
||||||
},
|
|
||||||
DefaultCallbacks: {
|
|
||||||
callback: function(form) {
|
|
||||||
return Form.serialize(form);
|
|
||||||
},
|
|
||||||
onComplete: function(transport, element) {
|
|
||||||
// For backward compatibility, this one is bound to the IPE, and passes
|
|
||||||
// the element directly. It was too often customized, so we don't break it.
|
|
||||||
new Effect.Highlight(element, {
|
|
||||||
startcolor: this.options.highlightColor, keepBackgroundImage: true });
|
|
||||||
},
|
|
||||||
onEnterEditMode: null,
|
|
||||||
onEnterHover: function(ipe) {
|
|
||||||
ipe.element.style.backgroundColor = ipe.options.highlightColor;
|
|
||||||
if (ipe._effect)
|
|
||||||
ipe._effect.cancel();
|
|
||||||
},
|
|
||||||
onFailure: function(transport, ipe) {
|
|
||||||
alert('Error communication with the server: ' + transport.responseText.stripTags());
|
|
||||||
},
|
|
||||||
onFormCustomization: null, // Takes the IPE and its generated form, after editor, before controls.
|
|
||||||
onLeaveEditMode: null,
|
|
||||||
onLeaveHover: function(ipe) {
|
|
||||||
ipe._effect = new Effect.Highlight(ipe.element, {
|
|
||||||
startcolor: ipe.options.highlightColor, endcolor: ipe.options.highlightEndColor,
|
|
||||||
restorecolor: ipe._originalBackground, keepBackgroundImage: true
|
|
||||||
});
|
|
||||||
}
|
|
||||||
},
|
|
||||||
Listeners: {
|
|
||||||
click: 'enterEditMode',
|
|
||||||
keydown: 'checkForEscapeOrReturn',
|
|
||||||
mouseover: 'enterHover',
|
|
||||||
mouseout: 'leaveHover'
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
Ajax.InPlaceCollectionEditor.DefaultOptions = {
|
|
||||||
loadingCollectionText: 'Loading options...'
|
|
||||||
};
|
|
||||||
|
|
||||||
// Delayed observer, like Form.Element.Observer,
|
|
||||||
// but waits for delay after last key input
|
|
||||||
// Ideal for live-search fields
|
|
||||||
|
|
||||||
Form.Element.DelayedObserver = Class.create({
|
|
||||||
initialize: function(element, delay, callback) {
|
|
||||||
this.delay = delay || 0.5;
|
|
||||||
this.element = $(element);
|
|
||||||
this.callback = callback;
|
|
||||||
this.timer = null;
|
|
||||||
this.lastValue = $F(this.element);
|
|
||||||
Event.observe(this.element,'keyup',this.delayedListener.bindAsEventListener(this));
|
|
||||||
},
|
|
||||||
delayedListener: function(event) {
|
|
||||||
if(this.lastValue == $F(this.element)) return;
|
|
||||||
if(this.timer) clearTimeout(this.timer);
|
|
||||||
this.timer = setTimeout(this.onTimerEvent.bind(this), this.delay * 1000);
|
|
||||||
this.lastValue = $F(this.element);
|
|
||||||
},
|
|
||||||
onTimerEvent: function() {
|
|
||||||
this.timer = null;
|
|
||||||
this.callback(this.element, $F(this.element));
|
|
||||||
}
|
|
||||||
});
|
|
File diff suppressed because it is too large
Load Diff
|
@ -1,68 +0,0 @@
|
||||||
// script.aculo.us scriptaculous.js v1.9.0, Thu Dec 23 16:54:48 -0500 2010
|
|
||||||
|
|
||||||
// Copyright (c) 2005-2010 Thomas Fuchs (http://script.aculo.us, http://mir.aculo.us)
|
|
||||||
//
|
|
||||||
// Permission is hereby granted, free of charge, to any person obtaining
|
|
||||||
// a copy of this software and associated documentation files (the
|
|
||||||
// "Software"), to deal in the Software without restriction, including
|
|
||||||
// without limitation the rights to use, copy, modify, merge, publish,
|
|
||||||
// distribute, sublicense, and/or sell copies of the Software, and to
|
|
||||||
// permit persons to whom the Software is furnished to do so, subject to
|
|
||||||
// the following conditions:
|
|
||||||
//
|
|
||||||
// The above copyright notice and this permission notice shall be
|
|
||||||
// included in all copies or substantial portions of the Software.
|
|
||||||
//
|
|
||||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
|
||||||
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|
||||||
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
|
||||||
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
|
||||||
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
|
||||||
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
|
||||||
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
||||||
//
|
|
||||||
// For details, see the script.aculo.us web site: http://script.aculo.us/
|
|
||||||
|
|
||||||
var Scriptaculous = {
|
|
||||||
Version: '1.9.0',
|
|
||||||
require: function(libraryName) {
|
|
||||||
try{
|
|
||||||
// inserting via DOM fails in Safari 2.0, so brute force approach
|
|
||||||
document.write('<script type="text/javascript" src="'+libraryName+'"><\/script>');
|
|
||||||
} catch(e) {
|
|
||||||
// for xhtml+xml served content, fall back to DOM methods
|
|
||||||
var script = document.createElement('script');
|
|
||||||
script.type = 'text/javascript';
|
|
||||||
script.src = libraryName;
|
|
||||||
document.getElementsByTagName('head')[0].appendChild(script);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
REQUIRED_PROTOTYPE: '1.6.0.3',
|
|
||||||
load: function() {
|
|
||||||
function convertVersionString(versionString) {
|
|
||||||
var v = versionString.replace(/_.*|\./g, '');
|
|
||||||
v = parseInt(v + '0'.times(4-v.length));
|
|
||||||
return versionString.indexOf('_') > -1 ? v-1 : v;
|
|
||||||
}
|
|
||||||
|
|
||||||
if((typeof Prototype=='undefined') ||
|
|
||||||
(typeof Element == 'undefined') ||
|
|
||||||
(typeof Element.Methods=='undefined') ||
|
|
||||||
(convertVersionString(Prototype.Version) <
|
|
||||||
convertVersionString(Scriptaculous.REQUIRED_PROTOTYPE)))
|
|
||||||
throw("script.aculo.us requires the Prototype JavaScript framework >= " +
|
|
||||||
Scriptaculous.REQUIRED_PROTOTYPE);
|
|
||||||
|
|
||||||
var js = /scriptaculous\.js(\?.*)?$/;
|
|
||||||
$$('script[src]').findAll(function(s) {
|
|
||||||
return s.src.match(js);
|
|
||||||
}).each(function(s) {
|
|
||||||
var path = s.src.replace(js, ''),
|
|
||||||
includes = s.src.match(/\?.*load=([a-z,]*)/);
|
|
||||||
(includes ? includes[1] : 'builder,effects,dragdrop,controls,slider,sound').split(',').each(
|
|
||||||
function(include) { Scriptaculous.require(path+include+'.js') });
|
|
||||||
});
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
Scriptaculous.load();
|
|
|
@ -2,8 +2,8 @@ Plugins.Af_Readability = {
|
||||||
orig_attr_name: 'data-readability-orig-content',
|
orig_attr_name: 'data-readability-orig-content',
|
||||||
self: this,
|
self: this,
|
||||||
embed: function(id) {
|
embed: function(id) {
|
||||||
const content = $$(App.isCombinedMode() ? ".cdm[data-article-id=" + id + "] .content-inner" :
|
const content = App.find(App.isCombinedMode() ? ".cdm[data-article-id=" + id + "] .content-inner" :
|
||||||
".post[data-article-id=" + id + "] .content")[0];
|
".post[data-article-id=" + id + "] .content");
|
||||||
|
|
||||||
if (content.hasAttribute(self.orig_attr_name)) {
|
if (content.hasAttribute(self.orig_attr_name)) {
|
||||||
content.innerHTML = content.getAttribute(self.orig_attr_name);
|
content.innerHTML = content.getAttribute(self.orig_attr_name);
|
||||||
|
|
|
@ -3,7 +3,7 @@ require(['dojo/_base/kernel', 'dojo/ready'], function (dojo, ready) {
|
||||||
PluginHost.register(PluginHost.HOOK_ARTICLE_RENDERED_CDM, function (row) {
|
PluginHost.register(PluginHost.HOOK_ARTICLE_RENDERED_CDM, function (row) {
|
||||||
if (row) {
|
if (row) {
|
||||||
|
|
||||||
row.select("video").each(function (v) {
|
row.querySelectorAll("video").forEach(function (v) {
|
||||||
v.muted = true;
|
v.muted = true;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -14,7 +14,7 @@ require(['dojo/_base/kernel', 'dojo/ready'], function (dojo, ready) {
|
||||||
PluginHost.register(PluginHost.HOOK_ARTICLE_RENDERED, function (row) {
|
PluginHost.register(PluginHost.HOOK_ARTICLE_RENDERED, function (row) {
|
||||||
if (row) {
|
if (row) {
|
||||||
|
|
||||||
row.select("video").each(function (v) {
|
row.querySelectorAll("video").forEach(function (v) {
|
||||||
v.muted = true;
|
v.muted = true;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,9 +23,6 @@ Plugins.Share = {
|
||||||
target.href = target.href.replace(/&key=.*$/,
|
target.href = target.href.replace(/&key=.*$/,
|
||||||
"&key=" + new_link);
|
"&key=" + new_link);
|
||||||
|
|
||||||
// eslint-disable-next-line no-new
|
|
||||||
new Effect.Highlight(target);
|
|
||||||
|
|
||||||
const icon = document.querySelector(".share-icon-" + id);
|
const icon = document.querySelector(".share-icon-" + id);
|
||||||
|
|
||||||
if (icon)
|
if (icon)
|
||||||
|
|
|
@ -7,8 +7,8 @@ Plugins.Shorten_Expanded = {
|
||||||
const row = $(id);
|
const row = $(id);
|
||||||
|
|
||||||
if (row) {
|
if (row) {
|
||||||
const content = row.select(".content-shrink-wrap")[0];
|
const content = row.querySelector(".content-shrink-wrap");
|
||||||
const link = row.select(".expand-prompt")[0];
|
const link = row.querySelector(".expand-prompt");
|
||||||
|
|
||||||
if (content) content.removeClassName("content-shrink-wrap");
|
if (content) content.removeClassName("content-shrink-wrap");
|
||||||
if (link) Element.hide(link);
|
if (link) Element.hide(link);
|
||||||
|
|
|
@ -59,8 +59,7 @@
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<?php
|
<?php
|
||||||
foreach (array("lib/prototype.js",
|
foreach (array(#"lib/prototype.js",
|
||||||
"lib/scriptaculous/scriptaculous.js?load=effects,controls",
|
|
||||||
"lib/dojo/dojo.js",
|
"lib/dojo/dojo.js",
|
||||||
"lib/dojo/tt-rss-layer.js",
|
"lib/dojo/tt-rss-layer.js",
|
||||||
"js/common.js",
|
"js/common.js",
|
||||||
|
|
Loading…
Reference in New Issue