summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rwxr-xr-xclasses/handler/public.php5
-rw-r--r--classes/pref/prefs.php2
-rw-r--r--index.php3
-rw-r--r--js/App.js75
-rw-r--r--js/Article.js36
-rw-r--r--js/CommonDialogs.js20
-rw-r--r--js/CommonFilters.js22
-rwxr-xr-xjs/FeedTree.js4
-rw-r--r--js/Feeds.js20
-rwxr-xr-xjs/Headlines.js171
-rw-r--r--js/PrefFeedTree.js10
-rw-r--r--js/PrefFilterTree.js4
-rw-r--r--js/PrefHelpers.js10
-rw-r--r--js/PrefLabelTree.js4
-rw-r--r--js/PrefUsers.js2
-rwxr-xr-xjs/common.js135
-rw-r--r--js/tt-rss.js15
-rw-r--r--js/utility.js2
-rw-r--r--lib/scriptaculous/controls.js965
-rw-r--r--lib/scriptaculous/effects.js1123
-rw-r--r--lib/scriptaculous/scriptaculous.js68
-rw-r--r--plugins/af_readability/init.js4
-rw-r--r--plugins/af_zz_vidmute/init.js4
-rw-r--r--plugins/share/share.js3
-rw-r--r--plugins/shorten_expanded/init.js4
-rw-r--r--prefs.php3
26 files changed, 319 insertions, 2395 deletions
diff --git a/classes/handler/public.php b/classes/handler/public.php
index b810019c1..80c1c271d 100755
--- a/classes/handler/public.php
+++ b/classes/handler/public.php
@@ -362,7 +362,6 @@ class Handler_Public extends Handler {
echo javascript_tag("lib/dojo/dojo.js");
echo javascript_tag("js/utility.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"/>
<link rel="shortcut icon" type="image/png" href="images/favicon.png">
@@ -388,10 +387,10 @@ class Handler_Public extends Handler {
ready(function() {
parser.parse();
- new Ajax.Autocompleter('labels_value', 'labels_choices',
+ /* new Ajax.Autocompleter('labels_value', 'labels_choices',
"backend.php?op=rpc&method=completeLabels",
{ tokens: ',', paramName: "search" });
- });
+ }); */
});
}
};
diff --git a/classes/pref/prefs.php b/classes/pref/prefs.php
index b760affa0..cfbf83d2a 100644
--- a/classes/pref/prefs.php
+++ b/classes/pref/prefs.php
@@ -366,7 +366,7 @@ class Pref_Prefs extends Handler_Protected {
if (warn) Element.hide(warn);
}
- new Effect.Appear('pwd_change_infobox');
+ Element.show('pwd_change_infobox');
})
}
</script>
diff --git a/index.php b/index.php
index d53fb54a8..4a4d336ca 100644
--- a/index.php
+++ b/index.php
@@ -76,8 +76,7 @@
</script>
<?php
- foreach (array("lib/prototype.js",
- "lib/scriptaculous/scriptaculous.js?load=effects,controls",
+ foreach (array(#"lib/_prototype.js",
"lib/dojo/dojo.js",
"lib/dojo/tt-rss-layer.js",
"js/tt-rss.js",
diff --git a/js/App.js b/js/App.js
index 75cf73288..0a66987ed 100644
--- a/js/App.js
+++ b/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) {
// elem could be a Dijit widget
@@ -140,21 +149,20 @@ const App = {
}
},
setupNightModeDetection: function(callback) {
- if (!$("theme_css")) {
+ if (!App.byId("theme_css")) {
const mql = window.matchMedia('(prefers-color-scheme: dark)');
try {
mql.addEventListener("change", () => {
- this.nightModeChanged(mql.matches, $("theme_auto_css"));
+ this.nightModeChanged(mql.matches, App.byId("theme_auto_css"));
});
} catch (e) {
console.warn("exception while trying to set MQL event listener");
}
- const link = new Element("link", {
- rel: "stylesheet",
- id: "theme_auto_css"
- });
+ const link = document.createElement("link");
+ link.rel = "stylesheet";
+ link.id = "theme_auto_css";
if (callback) {
link.onload = function() {
@@ -176,7 +184,7 @@ const App = {
if (callback) callback();
}
},
- enableCsrfSupport: function() {
+ /*enableCsrfSupport: function() {
const _this = this;
Ajax.Base.prototype.initialize = Ajax.Base.prototype.initialize.wrap(
@@ -196,7 +204,7 @@ const App = {
return callOriginal(options);
}
);
- },
+ }, */
postCurrentWindow: function(target, params) {
const form = document.createElement("form");
@@ -245,8 +253,13 @@ const App = {
}
},
- urlParam: function(param) {
- return String(window.location.href).parseQuery()[param];
+ urlParam: function(name) {
+ try {
+ const results = new RegExp('[\?&]' + name + '=([^&#]*)').exec(window.location.href);
+ return decodeURIComponent(results[1].replace(/\+/g, " ")) || 0;
+ } catch (e) {
+ return 0;
+ }
},
next_seq: function() {
this._rpc_seq += 1;
@@ -262,7 +275,7 @@ const App = {
dijit.byId("loading_bar").update({progress: this._loading_progress});
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) {
this.hotkey_prefix = keychar;
- $("cmdline").innerHTML = keychar;
+ App.byId("cmdline").innerHTML = keychar;
Element.show("cmdline");
window.clearTimeout(this.hotkey_prefix_timeout);
@@ -342,11 +355,11 @@ const App = {
cleanupMemory: function(root) {
const dijits = dojo.query("[widgetid]", dijit.byId(root).domNode).map(dijit.byNode);
- dijits.each(function (d) {
+ dijits.forEach(function (d) {
dojo.destroy(d.domNode);
});
- $$("#" + root + " *").each(function (i) {
+ App.findAll("#" + root + " *").forEach(function (i) {
i.parentNode ? i.parentNode.removeChild(i) : true;
});
},
@@ -364,9 +377,9 @@ const App = {
},
displayIfChecked: function(checkbox, elemId) {
if (checkbox.checked) {
- Effect.Appear(elemId, {duration : 0.5});
+ Element.show(elemId);
} else {
- Effect.Fade(elemId, {duration : 0.5});
+ Element.hide(elemId);
}
},
hotkeyHelp: function() {
@@ -381,7 +394,7 @@ const App = {
},
handleRpcJson: function(transport) {
- const netalert = $$("#toolbar .net-alert")[0];
+ const netalert = App.findAll("#toolbar .net-alert")[0];
try {
const reply = JSON.parse(transport.responseText);
@@ -459,7 +472,7 @@ const App = {
}
if (k == "recent_log_events") {
- const alert = $$(".log-alert")[0];
+ const alert = App.findAll(".log-alert")[0];
if (alert) {
v > 0 ? alert.show() : alert.hide();
@@ -516,7 +529,7 @@ const App = {
break;
case "cdm_auto_catchup":
if (params[k] == 1) {
- const hl = $("headlines-frame");
+ const hl = App.byId("headlines-frame");
if (hl) hl.addClassName("auto_catchup");
}
break;
@@ -562,7 +575,7 @@ const App = {
}
return this.report(error,
- Object.extend({title: __("Fatal error")}, params));
+ {...{title: __("Fatal error")}, ...params});
},
report: function(error, params = {}) {
if (!error) return;
@@ -650,7 +663,7 @@ const App = {
this.setLoadingProgress(30);
this.initHotkeyActions();
- this.enableCsrfSupport();
+ //this.enableCsrfSupport();
const params = {
op: "rpc",
@@ -671,7 +684,7 @@ const App = {
checkBrowserFeatures: function() {
let errorMsg = "";
- ['MutationObserver'].each(function(wf) {
+ ['MutationObserver'].forEach(function(wf) {
if (!(wf in window)) {
errorMsg = `Browser feature check failed: <code>window.${wf}</code> not found.`;
throw new Error(errorMsg);
@@ -794,9 +807,9 @@ const App = {
console.log('update reply', reply);
if (reply.id) {
- $("updates-available").show();
+ App.byId("updates-available").show();
} else {
- $("updates-available").hide();
+ App.byId("updates-available").hide();
}
});
},
@@ -812,7 +825,7 @@ const App = {
onViewModeChanged: function() {
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('');
},
@@ -851,8 +864,8 @@ const App = {
{width: Cookie.get("ttrss_ci_width") + "px" });
}
- $("headlines-frame").setStyle({ borderBottomWidth: '0px' });
- $("headlines-frame").addClassName("wide");
+ App.byId("headlines-frame").setStyle({ borderBottomWidth: '0px' });
+ App.byId("headlines-frame").addClassName("wide");
} else {
@@ -867,8 +880,8 @@ const App = {
{height: Cookie.get("ttrss_ci_height") + "px" });
}
- $("headlines-frame").setStyle({ borderBottomWidth: '1px' });
- $("headlines-frame").removeClassName("wide");
+ App.byId("headlines-frame").setStyle({ borderBottomWidth: '1px' });
+ App.byId("headlines-frame").removeClassName("wide");
}
@@ -1107,7 +1120,7 @@ const App = {
this.hotkey_actions["select_article_cursor"] = () => {
const id = Article.getUnderPointer();
if (id) {
- const row = $("RROW-" + id);
+ const row = App.byId("RROW-" + id);
if (row)
row.toggleClassName("Selected");
@@ -1234,7 +1247,7 @@ const App = {
}
break;
case "qmcHKhelp":
- this.hotkeyHelp();
+ this.helpDialog("main");
break;
default:
console.log("quickMenuGo: unknown action: " + opid);
diff --git a/js/Article.js b/js/Article.js
index 81917fd47..e7498f0b3 100644
--- a/js/Article.js
+++ b/js/Article.js
@@ -36,19 +36,19 @@ const Article = {
const score = prompt(__("Please enter new score for selected articles:"));
if (!isNaN(parseInt(score))) {
- ids.each((id) => {
- const row = $("RROW-" + id);
+ ids.forEach((id) => {
+ const row = App.byId("RROW-" + id);
if (row) {
row.setAttribute("data-score", score);
- const pic = row.select(".icon-score")[0];
+ const pic = row.querySelector(".icon-score");
pic.innerHTML = Article.getScorePic(score);
pic.setAttribute("title", score);
["score-low", "score-high", "score-half-low", "score-half-high", "score-neutral"]
- .each(function(scl) {
+ .forEach(function(scl) {
if (row.hasClassName(scl))
row.removeClassName(scl);
});
@@ -72,13 +72,13 @@ const Article = {
if (!isNaN(parseInt(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.setAttribute("title", score);
["score-low", "score-high", "score-half-low", "score-half-high", "score-neutral"]
- .each(function(scl) {
+ .forEach(function(scl) {
if (row.hasClassName(scl))
row.removeClassName(scl);
});
@@ -104,7 +104,7 @@ const Article = {
}
}, */
cdmUnsetActive: function (event) {
- const row = $("RROW-" + Article.getActive());
+ const row = App.byId("RROW-" + Article.getActive());
if (row) {
row.removeClassName("active");
@@ -249,7 +249,7 @@ const Article = {
container.innerHTML += "&nbsp;";
// 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.removeAttribute("data-content");
@@ -351,7 +351,7 @@ const Article = {
if (data) {
const id = data.id;
- const tags = $("ATSTR-" + id);
+ const tags = App.byId("ATSTR-" + id);
const tooltip = dijit.byId("ATSTRTIP-" + id);
if (tags) tags.innerHTML = data.content;
@@ -370,13 +370,13 @@ const Article = {
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('disabled', false);
- new Ajax.Autocompleter("tags_str", "tags_choices",
+ /* new Ajax.Autocompleter("tags_str", "tags_choices",
"backend.php?op=article&method=completeTags",
- {tokens: ',', paramName: "search"});
+ {tokens: ',', paramName: "search"}); */
});
});
@@ -386,8 +386,8 @@ const Article = {
cdmMoveToId: function (id, params = {}) {
const force_to_top = params.force_to_top || false;
- const ctr = $("headlines-frame");
- const row = $("RROW-" + id);
+ const ctr = App.byId("headlines-frame");
+ const row = App.byId("RROW-" + id);
if (!row || !ctr) return;
@@ -399,12 +399,12 @@ const Article = {
if (id != 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");
Article.pack(row);
});
- const row = $("RROW-" + id);
+ const row = App.byId("RROW-" + id);
if (row) {
Article.unpack(row);
@@ -425,10 +425,10 @@ const Article = {
return 0;
},
scrollByPages: function (page_offset) {
- App.Scrollable.scrollByPages($("content-insert"), page_offset);
+ App.Scrollable.scrollByPages(App.byId("content-insert"), page_offset);
},
scroll: function (offset) {
- App.Scrollable.scroll($("content-insert"), offset);
+ App.Scrollable.scroll(App.byId("content-insert"), offset);
},
mouseIn: function (id) {
this.post_under_pointer = id;
diff --git a/js/CommonDialogs.js b/js/CommonDialogs.js
index dd0d56194..40313d34f 100644
--- a/js/CommonDialogs.js
+++ b/js/CommonDialogs.js
@@ -25,7 +25,7 @@ const CommonDialogs = {
else
Feeds.reload();
- const icon = $$(".feed-editor-icon")[0];
+ const icon = App.findAll(".feed-editor-icon")[0];
if (icon)
icon.src = icon.src.replace(/\?[0-9]+$/, "?" + new Date().getTime());
@@ -36,7 +36,7 @@ const CommonDialogs = {
return false;
},
uploadFeedIcon: function() {
- const file = $("icon_file");
+ const file = App.byId("icon_file");
if (file.value.length == 0) {
alert(__("Please select an image file to upload."));
@@ -57,7 +57,7 @@ const CommonDialogs = {
else
Feeds.reload();
- const icon = $$(".feed-editor-icon")[0];
+ const icon = App.findAll(".feed-editor-icon")[0];
if (icon)
icon.src = icon.src.replace(/\?[0-9]+$/, "?" + new Date().getTime());
@@ -72,7 +72,7 @@ const CommonDialogs = {
break;
}
};
- xhr.send(new FormData($("feed_icon_upload_form")));
+ xhr.send(new FormData(App.byId("feed_icon_upload_form")));
}
return false;
@@ -165,13 +165,11 @@ const CommonDialogs = {
</form>
`,
show_error: function (msg) {
- const elem = $("fadd_error_message");
+ const elem = App.byId("fadd_error_message");
elem.innerHTML = msg;
- if (!Element.visible(elem))
- new Effect.Appear(elem);
-
+ Element.show(elem);
},
execute: function () {
if (this.validate()) {
@@ -239,7 +237,7 @@ const CommonDialogs = {
}
}
- Effect.Appear('feedDlg_feedsContainer', {duration: 0.5});
+ Element.show('feedDlg_feedsContainer');
}
break;
case 5:
@@ -463,8 +461,6 @@ const CommonDialogs = {
target.href = new_link;
target.innerHTML = new_link;
- new Effect.Highlight(target);
-
Notify.close();
} else {
@@ -528,8 +524,6 @@ const CommonDialogs = {
target.href = target.href.replace(/&key=.*$/,
"&key=" + new_link);
- new Effect.Highlight(target);
-
Notify.close();
} else {
diff --git a/js/CommonFilters.js b/js/CommonFilters.js
index e3629157b..d5b751f91 100644
--- a/js/CommonFilters.js
+++ b/js/CommonFilters.js
@@ -9,7 +9,7 @@ const Filters = {
filterDlgCheckAction: function(sender) {
const action = sender.value;
- const action_param = $("filterDlg_paramBox");
+ const action_param = App.byId("filterDlg_paramBox");
if (!action_param) {
console.log("filterDlgCheckAction: can't find action param box!");
@@ -18,7 +18,7 @@ const Filters = {
// if selected action supports parameters, enable params field
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_actionParamLabel").domNode);
@@ -97,7 +97,7 @@ const Filters = {
title: ruleStr ? __("Edit rule") : __("Add rule"),
execute: function () {
if (this.validate()) {
- Filters.createNewRuleElement($("filterDlg_Matches"), replaceNode);
+ Filters.createNewRuleElement(App.byId("filterDlg_Matches"), replaceNode);
this.hide();
}
},
@@ -119,7 +119,7 @@ const Filters = {
title: actionStr ? __("Edit action") : __("Add action"),
execute: function () {
if (this.validate()) {
- Filters.createNewActionElement($("filterDlg_Actions"), replaceNode);
+ Filters.createNewActionElement(App.byId("filterDlg_Actions"), replaceNode);
this.hide();
}
}
@@ -158,7 +158,7 @@ const Filters = {
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("%d", offset);
@@ -167,7 +167,7 @@ const Filters = {
for (let i = 0; i < result.length; 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) {
@@ -183,11 +183,11 @@ const Filters = {
Element.hide("prefFilterLoadingIndicator");
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>`;
- $("prefFilterProgressMsg").innerHTML = "Articles matching this filter:";
+ App.byId("prefFilterProgressMsg").innerHTML = "Articles matching this filter:";
} else {
- $("prefFilterProgressMsg").innerHTML = __("Found %d articles matching this filter:")
+ App.byId("prefFilterProgressMsg").innerHTML = __("Found %d articles matching this filter:")
.replace("%d", dialog.results);
}
@@ -289,12 +289,12 @@ const Filters = {
Filters.addFilterRule();
},
deleteAction: function () {
- $$("#filterDlg_Actions li[class*=Selected]").each(function (e) {
+ App.findAll("#filterDlg_Actions li[class*=Selected]").forEach(function (e) {
e.parentNode.removeChild(e)
});
},
deleteRule: function () {
- $$("#filterDlg_Matches li[class*=Selected]").each(function (e) {
+ App.findAll("#filterDlg_Matches li[class*=Selected]").forEach(function (e) {
e.parentNode.removeChild(e)
});
},
diff --git a/js/FeedTree.js b/js/FeedTree.js
index 694cf8332..17cd3deea 100755
--- a/js/FeedTree.js
+++ b/js/FeedTree.js
@@ -286,7 +286,7 @@ define(["dojo/_base/declare", "dojo/dom-construct", "dojo/_base/array", "dojo/co
// focus headlines to route key events there
setTimeout(() => {
- $("headlines-frame").focus();
+ App.byId("headlines-frame").focus();
if (treeNode) {
const node = treeNode.rowNode;
@@ -295,7 +295,7 @@ define(["dojo/_base/declare", "dojo/dom-construct", "dojo/_base/array", "dojo/co
if (node && tree) {
// scroll tree to selection if needed
if (node.offsetTop < tree.scrollTop || node.offsetTop > tree.scrollTop + tree.clientHeight) {
- $("feedTree").scrollTop = node.offsetTop;
+ App.byId("feedTree").scrollTop = node.offsetTop;
}
}
}
diff --git a/js/Feeds.js b/js/Feeds.js
index 0567cf8c5..7f3a80f4e 100644
--- a/js/Feeds.js
+++ b/js/Feeds.js
@@ -117,7 +117,7 @@ const Feeds = {
toggle: function() {
Element.toggle("feeds-holder");
- const splitter = $("feeds-holder_splitter");
+ const splitter = App.byId("feeds-holder_splitter");
Element.visible("feeds-holder") ? splitter.show() : splitter.hide();
@@ -180,7 +180,7 @@ const Feeds = {
dojo.disconnect(tmph);
});
- $("feeds-holder").appendChild(tree.domNode);
+ App.byId("feeds-holder").appendChild(tree.domNode);
const tmph2 = dojo.connect(tree, 'onLoad', function () {
dojo.disconnect(tmph2);
@@ -284,8 +284,8 @@ const Feeds = {
this._active_feed_id = id;
this._active_feed_is_cat = is_cat;
- $("headlines-frame").setAttribute("feed-id", id);
- $("headlines-frame").setAttribute("is-cat", is_cat ? 1 : 0);
+ App.byId("headlines-frame").setAttribute("feed-id", id);
+ App.byId("headlines-frame").setAttribute("is-cat", is_cat ? 1 : 0);
this.select(id, is_cat);
@@ -310,8 +310,8 @@ const Feeds = {
if (tree)
return tree.hideRead(hide, App.getInitParam("hide_read_shows_special"));*/
- $$("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-feeds", !!hide);
+ App.findAll("body")[0].setAttribute("hide-read-shows-special", !!App.getInitParam("hide_read_shows_special"));
},
open: function(params) {
const feed = params.feed;
@@ -339,7 +339,7 @@ const Feeds = {
}, 10 * 1000);
}
- Form.enable("toolbar-main");
+ //Form.enable("toolbar-main");
let query = Object.assign({op: "feeds", method: "view", feed: feed},
dojo.formToObject("toolbar-main"));
@@ -362,7 +362,7 @@ const Feeds = {
query.m = "ForceUpdate";
}
- Form.enable("toolbar-main");
+ //Form.enable("toolbar-main");
if (!delayed)
if (!this.setExpando(feed, is_cat,
@@ -476,9 +476,9 @@ const Feeds = {
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");
})
}
diff --git a/js/Headlines.js b/js/Headlines.js
index 128a7e571..143a42d0b 100755
--- a/js/Headlines.js
+++ b/js/Headlines.js
@@ -44,7 +44,7 @@ const Headlines = {
row_observer: new MutationObserver((mutations) => {
const modified = [];
- mutations.each((m) => {
+ mutations.forEach((m) => {
if (m.type == 'attributes' && ['class', 'data-score'].indexOf(m.attributeName) != -1) {
const row = m.target;
@@ -54,7 +54,7 @@ const Headlines = {
const hl = Headlines.headlines[id];
if (hl) {
- const hl_old = Object.extend({}, hl);
+ const hl_old = {...{}, ...hl};
hl.unread = row.hasClassName("Unread");
hl.marked = row.hasClassName("marked");
@@ -94,7 +94,7 @@ const Headlines = {
rescore: {},
};
- modified.each(function (m) {
+ modified.forEach(function (m) {
if (m.old.marked != m.new.marked)
ops.tmark.push(m.id);
@@ -118,29 +118,29 @@ const Headlines = {
}
});
- ops.select.each((row) => {
- const cb = dijit.getEnclosingWidget(row.select(".rchk")[0]);
+ ops.select.forEach((row) => {
+ const cb = dijit.getEnclosingWidget(row.querySelector(".rchk"));
if (cb)
cb.attr('checked', true);
});
- ops.deselect.each((row) => {
- const cb = dijit.getEnclosingWidget(row.select(".rchk")[0]);
+ ops.deselect.forEach((row) => {
+ const cb = dijit.getEnclosingWidget(row.querySelector(".rchk"));
if (cb && !row.hasClassName("active"))
cb.attr('checked', false);
});
- ops.activate.each((row) => {
- const cb = dijit.getEnclosingWidget(row.select(".rchk")[0]);
+ ops.activate.forEach((row) => {
+ const cb = dijit.getEnclosingWidget(row.querySelector(".rchk"));
if (cb)
cb.attr('checked', true);
});
- ops.deactivate.each((row) => {
- const cb = dijit.getEnclosingWidget(row.select(".rchk")[0]);
+ ops.deactivate.forEach((row) => {
+ const cb = dijit.getEnclosingWidget(row.querySelector(".rchk"));
if (cb && !row.hasClassName("Selected"))
cb.attr('checked', false);
@@ -167,7 +167,7 @@ const Headlines = {
const scores = Object.keys(ops.rescore);
if (scores.length != 0) {
- scores.each((score) => {
+ scores.forEach((score) => {
promises.push(xhrPost("backend.php",
{op: "article", method: "setScore", id: ops.rescore[score].toString(), score: score}));
});
@@ -211,7 +211,7 @@ const Headlines = {
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);
@@ -222,10 +222,10 @@ const Headlines = {
Headlines.toggleUnread(id, 0);
} 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
- $("headlines-frame").scrollTop -= scroll_position_A-scroll_position_B;
+ App.byId("headlines-frame").scrollTop -= scroll_position_A-scroll_position_B;
Article.cdmMoveToId(id);
}
@@ -252,7 +252,7 @@ const Headlines = {
return false;
},
initScrollHandler: function () {
- $("headlines-frame").onscroll = (event) => {
+ App.byId("headlines-frame").onscroll = (event) => {
clearTimeout(this._headlines_scroll_timeout);
this._headlines_scroll_timeout = window.setTimeout(function () {
//console.log('done scrolling', event);
@@ -262,8 +262,8 @@ const Headlines = {
},
loadMore: function () {
const view_mode = document.forms["toolbar-main"].view_mode.value;
- const unread_in_buffer = $$("#headlines-frame > div[id*=RROW][class*=Unread]").length;
- const num_all = $$("#headlines-frame > div[id*=RROW]").length;
+ const unread_in_buffer = App.findAll("#headlines-frame > div[id*=RROW][class*=Unread]").length;
+ const num_all = App.findAll("#headlines-frame > div[id*=RROW]").length;
const num_unread = Feeds.getUnread(Feeds.getActive(), Feeds.activeIsCat());
// TODO implement marked & published
@@ -289,10 +289,10 @@ const Headlines = {
Feeds.open({feed: Feeds.getActive(), is_cat: Feeds.activeIsCat(), offset: offset, append: true});
},
isChildVisible: function (elem) {
- return App.Scrollable.isChildVisible(elem, $("headlines-frame"));
+ return App.Scrollable.isChildVisible(elem, App.byId("headlines-frame"));
},
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++) {
const row = rows[i];
@@ -303,7 +303,7 @@ const Headlines = {
}
},
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++) {
if (App.Scrollable.isChildVisible(rows[i], container)) {
@@ -315,8 +315,8 @@ const Headlines = {
scrollHandler: function (/*event*/) {
try {
if (!Feeds.infscroll_disabled && !Feeds.infscroll_in_progress) {
- const hsp = $("headlines-spacer");
- const container = $("headlines-frame");
+ const hsp = App.byId("headlines-spacer");
+ const container = App.byId("headlines-frame");
if (hsp && hsp.previousSibling) {
const last_row = hsp.previousSibling;
@@ -333,7 +333,7 @@ const Headlines = {
}
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 */
if (container.scrollTop > 0)
@@ -342,12 +342,12 @@ const Headlines = {
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++) {
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");
} else {
break;
@@ -362,23 +362,23 @@ const Headlines = {
return this.headlines[id];
},
setCommonClasses: function () {
- $("headlines-frame").removeClassName("cdm");
- $("headlines-frame").removeClassName("normal");
+ App.byId("headlines-frame").removeClassName("cdm");
+ 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
- $("main").removeClassName("expandable");
- $("main").removeClassName("expanded");
+ App.byId("main").removeClassName("expandable");
+ App.byId("main").removeClassName("expanded");
if (App.isCombinedMode())
- $("main").addClassName(App.getInitParam("cdm_expanded") ? " expanded" : " expandable");
+ App.byId("main").addClassName(App.getInitParam("cdm_expanded") ? " expanded" : " expandable");
},
renderAgain: function () {
// TODO: wrap headline elements into a knockoutjs model to prevent all this stuff
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 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)
});
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)
});
@@ -431,7 +431,7 @@ const Headlines = {
const tmp = document.createElement("div");
tmp.innerHTML = vgrhdr;
- $("headlines-frame").appendChild(tmp.firstChild);
+ App.byId("headlines-frame").appendChild(tmp.firstChild);
this.vgroup_last_feed = hl.feed_id;
}
@@ -555,11 +555,11 @@ const Headlines = {
return tmp.firstChild;
},
updateCurrentUnread: function () {
- if ($("feed_current_unread")) {
+ if (App.byId("feed_current_unread")) {
const feed_unread = Feeds.getUnread(Feeds.getActive(), Feeds.activeIsCat());
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");
} else {
Element.hide("feed_current_unread");
@@ -653,15 +653,15 @@ const Headlines = {
// also called in renderAgain() after view mode switch
Headlines.setCommonClasses();
- $("headlines-frame").setAttribute("is-vfeed",
+ App.byId("headlines-frame").setAttribute("is-vfeed",
reply['headlines']['is_vfeed'] ? 1 : 0);
Article.setActive(0);
try {
- $("headlines-frame").removeClassName("smooth-scroll");
- $("headlines-frame").scrollTop = 0;
- $("headlines-frame").addClassName("smooth-scroll");
+ App.byId("headlines-frame").removeClassName("smooth-scroll");
+ App.byId("headlines-frame").scrollTop = 0;
+ App.byId("headlines-frame").addClassName("smooth-scroll");
} catch (e) {
console.warn(e);
}
@@ -669,27 +669,27 @@ const Headlines = {
this.headlines = [];
this.vgroup_last_feed = undefined;
- /*dojo.html.set($("toolbar-headlines"),
+ /*dojo.html.set(App.byId("toolbar-headlines"),
reply['headlines']['toolbar'],
{parseContent: true});*/
Headlines.renderToolbar(reply['headlines']);
if (typeof reply['headlines']['content'] == 'string') {
- $("headlines-frame").innerHTML = reply['headlines']['content'];
+ App.byId("headlines-frame").innerHTML = reply['headlines']['content'];
} else {
- $("headlines-frame").innerHTML = '';
+ App.byId("headlines-frame").innerHTML = '';
for (let i = 0; i < reply['headlines']['content'].length; 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;
}
}
- let hsp = $("headlines-spacer");
+ let hsp = App.byId("headlines-spacer");
if (!hsp) {
hsp = document.createElement("div");
@@ -706,7 +706,7 @@ const Headlines = {
/*
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>)" +
"</span>";
} */
@@ -716,7 +716,7 @@ const Headlines = {
} else if (headlines_count > 0 && feed_id == Feeds.getActive() && is_cat == Feeds.activeIsCat()) {
const c = dijit.byId("headlines-frame");
- let hsp = $("headlines-spacer");
+ let hsp = App.byId("headlines-spacer");
if (hsp)
c.domNode.removeChild(hsp);
@@ -724,13 +724,13 @@ const Headlines = {
let headlines_appended = 0;
if (typeof reply['headlines']['content'] == 'string') {
- $("headlines-frame").innerHTML = reply['headlines']['content'];
+ App.byId("headlines-frame").innerHTML = reply['headlines']['content'];
} else {
for (let i = 0; i < reply['headlines']['content'].length; i++) {
const hl = reply['headlines']['content'][i];
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;
++headlines_appended;
@@ -762,7 +762,7 @@ const Headlines = {
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 (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)
});
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)
});
@@ -826,8 +826,8 @@ const Headlines = {
return;
}
- ids.each((id) => {
- const row = $("RROW-" + id);
+ ids.forEach((id) => {
+ const row = App.byId("RROW-" + id);
if (row) {
switch (cmode) {
@@ -851,7 +851,7 @@ const Headlines = {
return;
}
- ids.each((id) => {
+ ids.forEach((id) => {
this.toggleMark(id);
});
},
@@ -863,19 +863,19 @@ const Headlines = {
return;
}
- ids.each((id) => {
+ ids.forEach((id) => {
this.togglePub(id);
});
},
toggleMark: function (id) {
- const row = $("RROW-" + id);
+ const row = App.byId("RROW-" + id);
if (row)
row.toggleClassName("marked");
},
togglePub: function (id) {
- const row = $("RROW-" + id);
+ const row = App.byId("RROW-" + id);
if (row)
row.toggleClassName("published");
@@ -889,7 +889,7 @@ const Headlines = {
let next_id = false;
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...');
current_id = Headlines.firstVisible();
prev_id = current_id;
@@ -928,15 +928,15 @@ const Headlines = {
}
} else if (App.isCombinedMode()) {
// 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 ctr = $("headlines-frame");
+ const row = App.byId("RROW-" + current_id);
+ const ctr = App.byId("headlines-frame");
if (row) {
const next = row.nextSibling;
// 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) {
- 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
if (ctr.scrollTop < offset)
@@ -948,8 +948,8 @@ const Headlines = {
if (prev_id || current_id) {
if (App.isCombinedMode()) {
window.requestAnimationFrame(() => {
- const row = $("RROW-" + current_id);
- const ctr = $("headlines-frame");
+ const row = App.byId("RROW-" + current_id);
+ const ctr = App.byId("headlines-frame");
const delta_px = Math.round(row.offsetTop) - Math.round(ctr.scrollTop);
console.log('moving back, delta_px', delta_px);
@@ -970,7 +970,7 @@ const Headlines = {
},
updateSelectedPrompt: function () {
const count = Headlines.getSelected().length;
- const elem = $("selected_prompt");
+ const elem = App.byId("selected_prompt");
if (elem) {
elem.innerHTML = ngettext("%d article selected",
@@ -980,7 +980,7 @@ const Headlines = {
}
},
toggleUnread: function (id, cmode) {
- const row = $("RROW-" + id);
+ const row = App.byId("RROW-" + id);
if (row) {
if (typeof cmode == "undefined") cmode = 2;
@@ -1068,7 +1068,7 @@ const Headlines = {
getSelected: function () {
const rv = [];
- $$("#headlines-frame > div[id*=RROW][class*=Selected]").each(
+ App.findAll("#headlines-frame > div[id*=RROW][class*=Selected]").forEach(
function (child) {
rv.push(child.getAttribute("data-article-id"));
});
@@ -1082,9 +1082,9 @@ const Headlines = {
getLoaded: function () {
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)) {
rv.push(child.getAttribute("data-article-id"));
}
@@ -1111,7 +1111,7 @@ const Headlines = {
if (start == stop)
return [start];
- const rows = $$("#headlines-frame > div[id*=RROW]");
+ const rows = App.findAll("#headlines-frame > div[id*=RROW]");
const results = [];
let collecting = false;
@@ -1158,10 +1158,7 @@ const Headlines = {
console.warn("select: unknown mode", mode);
}
- const rows = $$(query);
-
- for (let i = 0; i < rows.length; i++) {
- const row = rows[i];
+ App.findAll(query).forEach((row) => {
switch (mode) {
case "none":
@@ -1173,7 +1170,7 @@ const Headlines = {
default:
row.addClassName("Selected");
}
- }
+ });
},
catchupSelection: function () {
const rows = Headlines.getSelected();
@@ -1212,7 +1209,7 @@ const Headlines = {
if (!below) {
for (let i = 0; i < visible_ids.length; i++) {
if (visible_ids[i] != id) {
- const e = $("RROW-" + visible_ids[i]);
+ const e = App.byId("RROW-" + visible_ids[i]);
if (e && e.hasClassName("Unread")) {
ids_to_mark.push(visible_ids[i]);
@@ -1224,7 +1221,7 @@ const Headlines = {
} else {
for (let i = visible_ids.length - 1; i >= 0; i--) {
if (visible_ids[i] != id) {
- const e = $("RROW-" + visible_ids[i]);
+ const e = App.byId("RROW-" + visible_ids[i]);
if (e && e.hasClassName("Unread")) {
ids_to_mark.push(visible_ids[i]);
@@ -1243,7 +1240,7 @@ const Headlines = {
if (App.getInitParam("confirm_feed_catchup") != 1 || confirm(msg)) {
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");
}
}
@@ -1253,16 +1250,16 @@ const Headlines = {
const data = JSON.parse(transport.responseText);
if (data) {
- data['info-for-headlines'].each(function (elem) {
- $$(".HLLCTR-" + elem.id).each(function (ctr) {
+ data['info-for-headlines'].forEach(function (elem) {
+ App.findAll(".HLLCTR-" + elem.id).forEach(function (ctr) {
ctr.innerHTML = elem.labels;
});
});
}
},
scrollToArticleId: function (id) {
- const container = $("headlines-frame");
- const row = $("RROW-" + id);
+ const container = App.byId("headlines-frame");
+ const row = App.byId("RROW-" + id);
if (!container || !row) return;
@@ -1361,7 +1358,7 @@ const Headlines = {
const labelAddMenu = 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 name = label.caption;
@@ -1409,10 +1406,10 @@ const Headlines = {
}
},
scrollByPages: function (page_offset) {
- App.Scrollable.scrollByPages($("headlines-frame"), page_offset);
+ App.Scrollable.scrollByPages(App.byId("headlines-frame"), page_offset);
},
scroll: function (offset) {
- App.Scrollable.scroll($("headlines-frame"), offset);
+ App.Scrollable.scroll(App.byId("headlines-frame"), offset);
},
initHeadlinesMenu: function () {
if (!dijit.byId("headlinesMenu")) {
diff --git a/js/PrefFeedTree.js b/js/PrefFeedTree.js
index e081e2e31..92194e037 100644
--- a/js/PrefFeedTree.js
+++ b/js/PrefFeedTree.js
@@ -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";
},
reload: function() {
- const searchElem = $("feed_search");
+ const searchElem = App.byId("feed_search");
const search = (searchElem) ? searchElem.value : "";
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 rv = [];
- items.each(function (item) {
+ items.forEach(function (item) {
if (item.id[0].match("CAT:"))
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 rv = [];
- items.each(function (item) {
+ items.forEach(function (item) {
if (item.id[0].match("FEED:"))
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"),
getChildByName: function (name) {
let rv = null;
- this.getChildren().each(
+ this.getChildren().forEach(
function (child) {
if (child.name == name) {
rv = child;
@@ -329,7 +329,7 @@ define(["dojo/_base/declare", "dojo/dom-construct", "lib/CheckBoxTree", "dojo/_b
/* normalize unchecked checkboxes because [] is not serialized */
- Object.keys(query).each((key) => {
+ Object.keys(query).forEach((key) => {
const val = query[key];
if (typeof val == "object" && val.length == 0)
diff --git a/js/PrefFilterTree.js b/js/PrefFilterTree.js
index e7d4efdc1..3d00c730c 100644
--- a/js/PrefFilterTree.js
+++ b/js/PrefFilterTree.js
@@ -80,14 +80,14 @@ define(["dojo/_base/declare", "dojo/dom-construct", "lib/CheckBoxTree"], functio
const items = tree.model.getCheckedItems();
const rv = [];
- items.each(function (item) {
+ items.forEach(function (item) {
rv.push(tree.model.store.getValue(item, 'bare_id'));
});
return rv;
},
reload: function() {
- const user_search = $("filter_search");
+ const user_search = App.byId("filter_search");
let search = "";
if (user_search) { search = user_search.value; }
diff --git a/js/PrefHelpers.js b/js/PrefHelpers.js
index 671431c39..f3c44e30d 100644
--- a/js/PrefHelpers.js
+++ b/js/PrefHelpers.js
@@ -9,7 +9,7 @@ const Helpers = {
return Tables.getSelected("app-password-list");
},
updateContent: function(data) {
- $("app_passwords_holder").innerHTML = data;
+ App.byId("app_passwords_holder").innerHTML = data;
dojo.parser.parse("app_passwords_holder");
},
removeSelected: function() {
@@ -218,8 +218,8 @@ const Helpers = {
title: __("Customize stylesheet"),
apply: function() {
xhrPost("backend.php", this.attr('value'), () => {
- new Effect.Appear("css_edit_apply_msg");
- $("user_css_style").innerText = this.attr('value');
+ Element.show("css_edit_apply_msg");
+ App.byId("user_css_style").innerText = this.attr('value');
});
},
execute: function () {
@@ -291,7 +291,7 @@ const Helpers = {
},
OPML: {
import: function() {
- const opml_file = $("opml_file");
+ const opml_file = App.byId("opml_file");
if (opml_file.value.length == 0) {
alert(__("Please choose an OPML file first."));
@@ -333,7 +333,7 @@ const Helpers = {
dialog.show();
};
- xhr.send(new FormData($("opml_import_form")));
+ xhr.send(new FormData(App.byId("opml_import_form")));
return false;
}
diff --git a/js/PrefLabelTree.js b/js/PrefLabelTree.js
index f22423091..4392dfc44 100644
--- a/js/PrefLabelTree.js
+++ b/js/PrefLabelTree.js
@@ -48,7 +48,7 @@ define(["dojo/_base/declare", "dojo/dom-construct", "lib/CheckBoxTree", "dijit/f
const items = tree.model.getCheckedItems();
const rv = [];
- items.each(function(item) {
+ items.forEach(function(item) {
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;
}
- const e = $("icon-label-" + id);
+ const e = App.byId("icon-label-" + id);
if (e) {
if (bg) e.style.color = bg;
diff --git a/js/PrefUsers.js b/js/PrefUsers.js
index ebfe9231b..2e8c9c4a8 100644
--- a/js/PrefUsers.js
+++ b/js/PrefUsers.js
@@ -5,7 +5,7 @@
const Users = {
reload: function(sort) {
- const user_search = $("user_search");
+ const user_search = App.byId("user_search");
const search = user_search ? user_search.value : "";
xhrPost("backend.php", { op: "pref-users", sort: sort, search: search }, (transport) => {
diff --git a/js/common.js b/js/common.js
index fb5cc6531..982bb94a7 100755
--- a/js/common.js
+++ b/js/common.js
@@ -3,35 +3,117 @@
/* global dijit, __, App, Ajax */
/* eslint-disable no-new */
-/* error reporting shim */
-// TODO: deprecated; remove
-/* function exception_error(e, e_compat, filename, lineno, colno) {
- if (typeof e == "string")
- e = e_compat;
+Element.prototype.hasClassName = function(className) {
+ dojo.hasClass(this, className);
+};
+
+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();
+}
- App.Error.report(e, {filename: filename, lineno: lineno, colno: colno});
-} */
+Element.hasClassName = function (id, className) {
+ return document.getElementById(id).hasClassName(className);
+}
/* xhr shorthand helpers */
/* exported xhrPost */
-function xhrPost(url, params, complete) {
+function xhrPost(url, params = {}, complete = undefined) {
console.log("xhrPost:", params);
return new Promise((resolve, reject) => {
- new Ajax.Request(url, {
- parameters: params,
- onComplete: function(reply) {
- if (complete != undefined) complete(reply);
-
- resolve(reply);
- }
- });
+ if (typeof __csrf_token != "undefined")
+ params = {...params, ...{csrf_token: __csrf_token}};
+
+ 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 */
-function xhrJson(url, params, complete) {
+function xhrJson(url, params = {}, complete = undefined) {
return new Promise((resolve, reject) =>
xhrPost(url, params).then((reply) => {
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 */
/* exported Lists */
@@ -70,8 +145,8 @@ const Lists = {
checked ? row.addClassName("Selected") : row.removeClassName("Selected");
},
select: function(elemId, selected) {
- $(elemId).select("li").each((row) => {
- const checkNode = row.select(".dijitCheckBox,input[type=checkbox]")[0];
+ $(elemId).querySelectorAll("li").forEach((row) => {
+ const checkNode = row.querySelector(".dijitCheckBox,input[type=checkbox]");
if (checkNode) {
const widget = dijit.getEnclosingWidget(checkNode);
@@ -101,8 +176,8 @@ const Tables = {
},
select: function(elemId, selected) {
- $(elemId).select("tr").each((row) => {
- const checkNode = row.select(".dijitCheckBox,input[type=checkbox]")[0];
+ $(elemId).querySelector("tr").forEach((row) => {
+ const checkNode = row.querySelector(".dijitCheckBox,input[type=checkbox]");
if (checkNode) {
const widget = dijit.getEnclosingWidget(checkNode);
@@ -119,7 +194,7 @@ const Tables = {
getSelected: function(elemId) {
const rv = [];
- $(elemId).select("tr").each((row) => {
+ $(elemId).querySelector("tr").forEach((row) => {
if (row.hasClassName("Selected")) {
// either older prefix-XXX notation or separate attribute
const rowId = row.getAttribute("data-row-id") || row.id.replace(/^[A-Z]*?-/, "");
@@ -173,7 +248,7 @@ const Notify = {
kind = kind || this.KIND_GENERIC;
keep = keep || false;
- const notify = $("notify");
+ const notify = App.byId("notify");
window.clearTimeout(this.timeout);
diff --git a/js/tt-rss.js b/js/tt-rss.js
index 764667a0d..28b598c25 100644
--- a/js/tt-rss.js
+++ b/js/tt-rss.js
@@ -70,13 +70,20 @@ require(["dojo/_base/kernel",
/* exported hash_get */
function hash_get(key) {
- const kv = window.location.hash.substring(1).toQueryParams();
- return kv[key];
+ console.warn("FIXME: hash_get", key);
+
+ //const kv = window.location.hash.substring(1).toQueryParams();
+ //return kv[key];
+ console.warn("FIXME: hash_get", key);
}
/* exported hash_set */
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;
- window.location.hash = $H(kv).toQueryString();
+ window.location.hash = $H(kv).toQueryString();*/
+
+ console.warn("FIXME: hash_set", key);
}
diff --git a/js/utility.js b/js/utility.js
index eef1c6b61..a7530a97f 100644
--- a/js/utility.js
+++ b/js/utility.js
@@ -2,7 +2,7 @@
/* 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 = {
apply_night_mode: function (is_night, link) {
console.log("night mode changed to", is_night);
diff --git a/lib/scriptaculous/controls.js b/lib/scriptaculous/controls.js
deleted file mode 100644
index 5137ab510..000000000
--- a/lib/scriptaculous/controls.js
+++ /dev/null
@@ -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 <[email protected]> (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));
- }
-}); \ No newline at end of file
diff --git a/lib/scriptaculous/effects.js b/lib/scriptaculous/effects.js
deleted file mode 100644
index 860ddc093..000000000
--- a/lib/scriptaculous/effects.js
+++ /dev/null
@@ -1,1123 +0,0 @@
-// script.aculo.us effects.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)
-// Contributors:
-// Justin Palmer (http://encytemedia.com/)
-// Mark Pilgrim (http://diveintomark.org/)
-// Martin Bialasinki
-//
-// 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/
-
-// converts rgb() and #xxx to #xxxxxx format,
-// returns self (or first argument) if not convertable
-String.prototype.parseColor = function() {
- var color = '#';
- if (this.slice(0,4) == 'rgb(') {
- var cols = this.slice(4,this.length-1).split(',');
- var i=0; do { color += parseInt(cols[i]).toColorPart() } while (++i<3);
- } else {
- if (this.slice(0,1) == '#') {
- if (this.length==4) for(var i=1;i<4;i++) color += (this.charAt(i) + this.charAt(i)).toLowerCase();
- if (this.length==7) color = this.toLowerCase();
- }
- }
- return (color.length==7 ? color : (arguments[0] || this));
-};
-
-/*--------------------------------------------------------------------------*/
-
-Element.collectTextNodes = function(element) {
- return $A($(element).childNodes).collect( function(node) {
- return (node.nodeType==3 ? node.nodeValue :
- (node.hasChildNodes() ? Element.collectTextNodes(node) : ''));
- }).flatten().join('');
-};
-
-Element.collectTextNodesIgnoreClass = function(element, className) {
- return $A($(element).childNodes).collect( function(node) {
- return (node.nodeType==3 ? node.nodeValue :
- ((node.hasChildNodes() && !Element.hasClassName(node,className)) ?
- Element.collectTextNodesIgnoreClass(node, className) : ''));
- }).flatten().join('');
-};
-
-Element.setContentZoom = function(element, percent) {
- element = $(element);
- element.setStyle({fontSize: (percent/100) + 'em'});
- if (Prototype.Browser.WebKit) window.scrollBy(0,0);
- return element;
-};
-
-Element.getInlineOpacity = function(element){
- return $(element).style.opacity || '';
-};
-
-Element.forceRerendering = function(element) {
- try {
- element = $(element);
- var n = document.createTextNode(' ');
- element.appendChild(n);
- element.removeChild(n);
- } catch(e) { }
-};
-
-/*--------------------------------------------------------------------------*/
-
-var Effect = {
- _elementDoesNotExistError: {
- name: 'ElementDoesNotExistError',
- message: 'The specified DOM element does not exist, but is required for this effect to operate'
- },
- Transitions: {
- linear: Prototype.K,
- sinoidal: function(pos) {
- return (-Math.cos(pos*Math.PI)/2) + .5;
- },
- reverse: function(pos) {
- return 1-pos;
- },
- flicker: function(pos) {
- var pos = ((-Math.cos(pos*Math.PI)/4) + .75) + Math.random()/4;
- return pos > 1 ? 1 : pos;
- },
- wobble: function(pos) {
- return (-Math.cos(pos*Math.PI*(9*pos))/2) + .5;
- },
- pulse: function(pos, pulses) {
- return (-Math.cos((pos*((pulses||5)-.5)*2)*Math.PI)/2) + .5;
- },
- spring: function(pos) {
- return 1 - (Math.cos(pos * 4.5 * Math.PI) * Math.exp(-pos * 6));
- },
- none: function(pos) {
- return 0;
- },
- full: function(pos) {
- return 1;
- }
- },
- DefaultOptions: {
- duration: 1.0, // seconds
- fps: 100, // 100= assume 66fps max.
- sync: false, // true for combining
- from: 0.0,
- to: 1.0,
- delay: 0.0,
- queue: 'parallel'
- },
- tagifyText: function(element) {
- var tagifyStyle = 'position:relative';
- if (Prototype.Browser.IE) tagifyStyle += ';zoom:1';
-
- element = $(element);
- $A(element.childNodes).each( function(child) {
- if (child.nodeType==3) {
- child.nodeValue.toArray().each( function(character) {
- element.insertBefore(
- new Element('span', {style: tagifyStyle}).update(
- character == ' ' ? String.fromCharCode(160) : character),
- child);
- });
- Element.remove(child);
- }
- });
- },
- multiple: function(element, effect) {
- var elements;
- if (((typeof element == 'object') ||
- Object.isFunction(element)) &&
- (element.length))
- elements = element;
- else
- elements = $(element).childNodes;
-
- var options = Object.extend({
- speed: 0.1,
- delay: 0.0
- }, arguments[2] || { });
- var masterDelay = options.delay;
-
- $A(elements).each( function(element, index) {
- new effect(element, Object.extend(options, { delay: index * options.speed + masterDelay }));
- });
- },
- PAIRS: {
- 'slide': ['SlideDown','SlideUp'],
- 'blind': ['BlindDown','BlindUp'],
- 'appear': ['Appear','Fade']
- },
- toggle: function(element, effect, options) {
- element = $(element);
- effect = (effect || 'appear').toLowerCase();
-
- return Effect[ Effect.PAIRS[ effect ][ element.visible() ? 1 : 0 ] ](element, Object.extend({
- queue: { position:'end', scope:(element.id || 'global'), limit: 1 }
- }, options || {}));
- }
-};
-
-Effect.DefaultOptions.transition = Effect.Transitions.sinoidal;
-
-/* ------------- core effects ------------- */
-
-Effect.ScopedQueue = Class.create(Enumerable, {
- initialize: function() {
- this.effects = [];
- this.interval = null;
- },
- _each: function(iterator) {
- this.effects._each(iterator);
- },
- add: function(effect) {
- var timestamp = new Date().getTime();
-
- var position = Object.isString(effect.options.queue) ?
- effect.options.queue : effect.options.queue.position;
-
- switch(position) {
- case 'front':
- // move unstarted effects after this effect
- this.effects.findAll(function(e){ return e.state=='idle' }).each( function(e) {
- e.startOn += effect.finishOn;
- e.finishOn += effect.finishOn;
- });
- break;
- case 'with-last':
- timestamp = this.effects.pluck('startOn').max() || timestamp;
- break;
- case 'end':
- // start effect after last queued effect has finished
- timestamp = this.effects.pluck('finishOn').max() || timestamp;
- break;
- }
-
- effect.startOn += timestamp;
- effect.finishOn += timestamp;
-
- if (!effect.options.queue.limit || (this.effects.length < effect.options.queue.limit))
- this.effects.push(effect);
-
- if (!this.interval)
- this.interval = setInterval(this.loop.bind(this), 15);
- },
- remove: function(effect) {
- this.effects = this.effects.reject(function(e) { return e==effect });
- if (this.effects.length == 0) {
- clearInterval(this.interval);
- this.interval = null;
- }
- },
- loop: function() {
- var timePos = new Date().getTime();
- for(var i=0, len=this.effects.length;i<len;i++)
- this.effects[i] && this.effects[i].loop(timePos);
- }
-});
-
-Effect.Queues = {
- instances: $H(),
- get: function(queueName) {
- if (!Object.isString(queueName)) return queueName;
-
- return this.instances.get(queueName) ||
- this.instances.set(queueName, new Effect.ScopedQueue());
- }
-};
-Effect.Queue = Effect.Queues.get('global');
-
-Effect.Base = Class.create({
- position: null,
- start: function(options) {
- if (options && options.transition === false) options.transition = Effect.Transitions.linear;
- this.options = Object.extend(Object.extend({ },Effect.DefaultOptions), options || { });
- this.currentFrame = 0;
- this.state = 'idle';
- this.startOn = this.options.delay*1000;
- this.finishOn = this.startOn+(this.options.duration*1000);
- this.fromToDelta = this.options.to-this.options.from;
- this.totalTime = this.finishOn-this.startOn;
- this.totalFrames = this.options.fps*this.options.duration;
-
- this.render = (function() {
- function dispatch(effect, eventName) {
- if (effect.options[eventName + 'Internal'])
- effect.options[eventName + 'Internal'](effect);
- if (effect.options[eventName])
- effect.options[eventName](effect);
- }
-
- return function(pos) {
- if (this.state === "idle") {
- this.state = "running";
- dispatch(this, 'beforeSetup');
- if (this.setup) this.setup();
- dispatch(this, 'afterSetup');
- }
- if (this.state === "running") {
- pos = (this.options.transition(pos) * this.fromToDelta) + this.options.from;
- this.position = pos;
- dispatch(this, 'beforeUpdate');
- if (this.update) this.update(pos);
- dispatch(this, 'afterUpdate');
- }
- };
- })();
-
- this.event('beforeStart');
- if (!this.options.sync)
- Effect.Queues.get(Object.isString(this.options.queue) ?
- 'global' : this.options.queue.scope).add(this);
- },
- loop: function(timePos) {
- if (timePos >= this.startOn) {
- if (timePos >= this.finishOn) {
- this.render(1.0);
- this.cancel();
- this.event('beforeFinish');
- if (this.finish) this.finish();
- this.event('afterFinish');
- return;
- }
- var pos = (timePos - this.startOn) / this.totalTime,
- frame = (pos * this.totalFrames).round();
- if (frame > this.currentFrame) {
- this.render(pos);
- this.currentFrame = frame;
- }
- }
- },
- cancel: function() {
- if (!this.options.sync)
- Effect.Queues.get(Object.isString(this.options.queue) ?
- 'global' : this.options.queue.scope).remove(this);
- this.state = 'finished';
- },
- event: function(eventName) {
- if (this.options[eventName + 'Internal']) this.options[eventName + 'Internal'](this);
- if (this.options[eventName]) this.options[eventName](this);
- },
- inspect: function() {
- var data = $H();
- for(property in this)
- if (!Object.isFunction(this[property])) data.set(property, this[property]);
- return '#<Effect:' + data.inspect() + ',options:' + $H(this.options).inspect() + '>';
- }
-});
-
-Effect.Parallel = Class.create(Effect.Base, {
- initialize: function(effects) {
- this.effects = effects || [];
- this.start(arguments[1]);
- },
- update: function(position) {
- this.effects.invoke('render', position);
- },
- finish: function(position) {
- this.effects.each( function(effect) {
- effect.render(1.0);
- effect.cancel();
- effect.event('beforeFinish');
- if (effect.finish) effect.finish(position);
- effect.event('afterFinish');
- });
- }
-});
-
-Effect.Tween = Class.create(Effect.Base, {
- initialize: function(object, from, to) {
- object = Object.isString(object) ? $(object) : object;
- var args = $A(arguments), method = args.last(),
- options = args.length == 5 ? args[3] : null;
- this.method = Object.isFunction(method) ? method.bind(object) :
- Object.isFunction(object[method]) ? object[method].bind(object) :
- function(value) { object[method] = value };
- this.start(Object.extend({ from: from, to: to }, options || { }));
- },
- update: function(position) {
- this.method(position);
- }
-});
-
-Effect.Event = Class.create(Effect.Base, {
- initialize: function() {
- this.start(Object.extend({ duration: 0 }, arguments[0] || { }));
- },
- update: Prototype.emptyFunction
-});
-
-Effect.Opacity = Class.create(Effect.Base, {
- initialize: function(element) {
- this.element = $(element);
- if (!this.element) throw(Effect._elementDoesNotExistError);
- // make this work on IE on elements without 'layout'
- if (Prototype.Browser.IE && (!this.element.currentStyle.hasLayout))
- this.element.setStyle({zoom: 1});
- var options = Object.extend({
- from: this.element.getOpacity() || 0.0,
- to: 1.0
- }, arguments[1] || { });
- this.start(options);
- },
- update: function(position) {
- this.element.setOpacity(position);
- }
-});
-
-Effect.Move = Class.create(Effect.Base, {
- initialize: function(element) {
- this.element = $(element);
- if (!this.element) throw(Effect._elementDoesNotExistError);
- var options = Object.extend({
- x: 0,
- y: 0,
- mode: 'relative'
- }, arguments[1] || { });
- this.start(options);
- },
- setup: function() {
- this.element.makePositioned();
- this.originalLeft = parseFloat(this.element.getStyle('left') || '0');
- this.originalTop = parseFloat(this.element.getStyle('top') || '0');
- if (this.options.mode == 'absolute') {
- this.options.x = this.options.x - this.originalLeft;
- this.options.y = this.options.y - this.originalTop;
- }
- },
- update: function(position) {
- this.element.setStyle({
- left: (this.options.x * position + this.originalLeft).round() + 'px',
- top: (this.options.y * position + this.originalTop).round() + 'px'
- });
- }
-});
-
-// for backwards compatibility
-Effect.MoveBy = function(element, toTop, toLeft) {
- return new Effect.Move(element,
- Object.extend({ x: toLeft, y: toTop }, arguments[3] || { }));
-};
-
-Effect.Scale = Class.create(Effect.Base, {
- initialize: function(element, percent) {
- this.element = $(element);
- if (!this.element) throw(Effect._elementDoesNotExistError);
- var options = Object.extend({
- scaleX: true,
- scaleY: true,
- scaleContent: true,
- scaleFromCenter: false,
- scaleMode: 'box', // 'box' or 'contents' or { } with provided values
- scaleFrom: 100.0,
- scaleTo: percent
- }, arguments[2] || { });
- this.start(options);
- },
- setup: function() {
- this.restoreAfterFinish = this.options.restoreAfterFinish || false;
- this.elementPositioning = this.element.getStyle('position');
-
- this.originalStyle = { };
- ['top','left','width','height','fontSize'].each( function(k) {
- this.originalStyle[k] = this.element.style[k];
- }.bind(this));
-
- this.originalTop = this.element.offsetTop;
- this.originalLeft = this.element.offsetLeft;
-
- var fontSize = this.element.getStyle('font-size') || '100%';
- ['em','px','%','pt'].each( function(fontSizeType) {
- if (fontSize.indexOf(fontSizeType)>0) {
- this.fontSize = parseFloat(fontSize);
- this.fontSizeType = fontSizeType;
- }
- }.bind(this));
-
- this.factor = (this.options.scaleTo - this.options.scaleFrom)/100;
-
- this.dims = null;
- if (this.options.scaleMode=='box')
- this.dims = [this.element.offsetHeight, this.element.offsetWidth];
- if (/^content/.test(this.options.scaleMode))
- this.dims = [this.element.scrollHeight, this.element.scrollWidth];
- if (!this.dims)
- this.dims = [this.options.scaleMode.originalHeight,
- this.options.scaleMode.originalWidth];
- },
- update: function(position) {
- var currentScale = (this.options.scaleFrom/100.0) + (this.factor * position);
- if (this.options.scaleContent && this.fontSize)
- this.element.setStyle({fontSize: this.fontSize * currentScale + this.fontSizeType });
- this.setDimensions(this.dims[0] * currentScale, this.dims[1] * currentScale);
- },
- finish: function(position) {
- if (this.restoreAfterFinish) this.element.setStyle(this.originalStyle);
- },
- setDimensions: function(height, width) {
- var d = { };
- if (this.options.scaleX) d.width = width.round() + 'px';
- if (this.options.scaleY) d.height = height.round() + 'px';
- if (this.options.scaleFromCenter) {
- var topd = (height - this.dims[0])/2;
- var leftd = (width - this.dims[1])/2;
- if (this.elementPositioning == 'absolute') {
- if (this.options.scaleY) d.top = this.originalTop-topd + 'px';
- if (this.options.scaleX) d.left = this.originalLeft-leftd + 'px';
- } else {
- if (this.options.scaleY) d.top = -topd + 'px';
- if (this.options.scaleX) d.left = -leftd + 'px';
- }
- }
- this.element.setStyle(d);
- }
-});
-
-Effect.Highlight = Class.create(Effect.Base, {
- initialize: function(element) {
- this.element = $(element);
- if (!this.element) throw(Effect._elementDoesNotExistError);
- var options = Object.extend({ startcolor: '#ffff99' }, arguments[1] || { });
- this.start(options);
- },
- setup: function() {
- // Prevent executing on elements not in the layout flow
- if (this.element.getStyle('display')=='none') { this.cancel(); return; }
- // Disable background image during the effect
- this.oldStyle = { };
- if (!this.options.keepBackgroundImage) {
- this.oldStyle.backgroundImage = this.element.getStyle('background-image');
- this.element.setStyle({backgroundImage: 'none'});
- }
- if (!this.options.endcolor)
- this.options.endcolor = this.element.getStyle('background-color').parseColor('#ffffff');
- if (!this.options.restorecolor)
- this.options.restorecolor = this.element.getStyle('background-color');
- // init color calculations
- this._base = $R(0,2).map(function(i){ return parseInt(this.options.startcolor.slice(i*2+1,i*2+3),16) }.bind(this));
- this._delta = $R(0,2).map(function(i){ return parseInt(this.options.endcolor.slice(i*2+1,i*2+3),16)-this._base[i] }.bind(this));
- },
- update: function(position) {
- this.element.setStyle({backgroundColor: $R(0,2).inject('#',function(m,v,i){
- return m+((this._base[i]+(this._delta[i]*position)).round().toColorPart()); }.bind(this)) });
- },
- finish: function() {
- this.element.setStyle(Object.extend(this.oldStyle, {
- backgroundColor: this.options.restorecolor
- }));
- }
-});
-
-Effect.ScrollTo = function(element) {
- var options = arguments[1] || { },
- scrollOffsets = document.viewport.getScrollOffsets(),
- elementOffsets = $(element).cumulativeOffset();
-
- if (options.offset) elementOffsets[1] += options.offset;
-
- return new Effect.Tween(null,
- scrollOffsets.top,
- elementOffsets[1],
- options,
- function(p){ scrollTo(scrollOffsets.left, p.round()); }
- );
-};
-
-/* ------------- combination effects ------------- */
-
-Effect.Fade = function(element) {
- element = $(element);
- var oldOpacity = element.getInlineOpacity();
- var options = Object.extend({
- from: element.getOpacity() || 1.0,
- to: 0.0,
- afterFinishInternal: function(effect) {
- if (effect.options.to!=0) return;
- effect.element.hide().setStyle({opacity: oldOpacity});
- }
- }, arguments[1] || { });
- return new Effect.Opacity(element,options);
-};
-
-Effect.Appear = function(element) {
- element = $(element);
- var options = Object.extend({
- from: (element.getStyle('display') == 'none' ? 0.0 : element.getOpacity() || 0.0),
- to: 1.0,
- // force Safari to render floated elements properly
- afterFinishInternal: function(effect) {
- effect.element.forceRerendering();
- },
- beforeSetup: function(effect) {
- effect.element.setOpacity(effect.options.from).show();
- }}, arguments[1] || { });
- return new Effect.Opacity(element,options);
-};
-
-Effect.Puff = function(element) {
- element = $(element);
- var oldStyle = {
- opacity: element.getInlineOpacity(),
- position: element.getStyle('position'),
- top: element.style.top,
- left: element.style.left,
- width: element.style.width,
- height: element.style.height
- };
- return new Effect.Parallel(
- [ new Effect.Scale(element, 200,
- { sync: true, scaleFromCenter: true, scaleContent: true, restoreAfterFinish: true }),
- new Effect.Opacity(element, { sync: true, to: 0.0 } ) ],
- Object.extend({ duration: 1.0,
- beforeSetupInternal: function(effect) {
- Position.absolutize(effect.effects[0].element);
- },
- afterFinishInternal: function(effect) {
- effect.effects[0].element.hide().setStyle(oldStyle); }
- }, arguments[1] || { })
- );
-};
-
-Effect.BlindUp = function(element) {
- element = $(element);
- element.makeClipping();
- return new Effect.Scale(element, 0,
- Object.extend({ scaleContent: false,
- scaleX: false,
- restoreAfterFinish: true,
- afterFinishInternal: function(effect) {
- effect.element.hide().undoClipping();
- }
- }, arguments[1] || { })
- );
-};
-
-Effect.BlindDown = function(element) {
- element = $(element);
- var elementDimensions = element.getDimensions();
- return new Effect.Scale(element, 100, Object.extend({
- scaleContent: false,
- scaleX: false,
- scaleFrom: 0,
- scaleMode: {originalHeight: elementDimensions.height, originalWidth: elementDimensions.width},
- restoreAfterFinish: true,
- afterSetup: function(effect) {
- effect.element.makeClipping().setStyle({height: '0px'}).show();
- },
- afterFinishInternal: function(effect) {
- effect.element.undoClipping();
- }
- }, arguments[1] || { }));
-};
-
-Effect.SwitchOff = function(element) {
- element = $(element);
- var oldOpacity = element.getInlineOpacity();
- return new Effect.Appear(element, Object.extend({
- duration: 0.4,
- from: 0,
- transition: Effect.Transitions.flicker,
- afterFinishInternal: function(effect) {
- new Effect.Scale(effect.element, 1, {
- duration: 0.3, scaleFromCenter: true,
- scaleX: false, scaleContent: false, restoreAfterFinish: true,
- beforeSetup: function(effect) {
- effect.element.makePositioned().makeClipping();
- },
- afterFinishInternal: function(effect) {
- effect.element.hide().undoClipping().undoPositioned().setStyle({opacity: oldOpacity});
- }
- });
- }
- }, arguments[1] || { }));
-};
-
-Effect.DropOut = function(element) {
- element = $(element);
- var oldStyle = {
- top: element.getStyle('top'),
- left: element.getStyle('left'),
- opacity: element.getInlineOpacity() };
- return new Effect.Parallel(
- [ new Effect.Move(element, {x: 0, y: 100, sync: true }),
- new Effect.Opacity(element, { sync: true, to: 0.0 }) ],
- Object.extend(
- { duration: 0.5,
- beforeSetup: function(effect) {
- effect.effects[0].element.makePositioned();
- },
- afterFinishInternal: function(effect) {
- effect.effects[0].element.hide().undoPositioned().setStyle(oldStyle);
- }
- }, arguments[1] || { }));
-};
-
-Effect.Shake = function(element) {
- element = $(element);
- var options = Object.extend({
- distance: 20,
- duration: 0.5
- }, arguments[1] || {});
- var distance = parseFloat(options.distance);
- var split = parseFloat(options.duration) / 10.0;
- var oldStyle = {
- top: element.getStyle('top'),
- left: element.getStyle('left') };
- return new Effect.Move(element,
- { x: distance, y: 0, duration: split, afterFinishInternal: function(effect) {
- new Effect.Move(effect.element,
- { x: -distance*2, y: 0, duration: split*2, afterFinishInternal: function(effect) {
- new Effect.Move(effect.element,
- { x: distance*2, y: 0, duration: split*2, afterFinishInternal: function(effect) {
- new Effect.Move(effect.element,
- { x: -distance*2, y: 0, duration: split*2, afterFinishInternal: function(effect) {
- new Effect.Move(effect.element,
- { x: distance*2, y: 0, duration: split*2, afterFinishInternal: function(effect) {
- new Effect.Move(effect.element,
- { x: -distance, y: 0, duration: split, afterFinishInternal: function(effect) {
- effect.element.undoPositioned().setStyle(oldStyle);
- }}); }}); }}); }}); }}); }});
-};
-
-Effect.SlideDown = function(element) {
- element = $(element).cleanWhitespace();
- // SlideDown need to have the content of the element wrapped in a container element with fixed height!
- var oldInnerBottom = element.down().getStyle('bottom');
- var elementDimensions = element.getDimensions();
- return new Effect.Scale(element, 100, Object.extend({
- scaleContent: false,
- scaleX: false,
- scaleFrom: window.opera ? 0 : 1,
- scaleMode: {originalHeight: elementDimensions.height, originalWidth: elementDimensions.width},
- restoreAfterFinish: true,
- afterSetup: function(effect) {
- effect.element.makePositioned();
- effect.element.down().makePositioned();
- if (window.opera) effect.element.setStyle({top: ''});
- effect.element.makeClipping().setStyle({height: '0px'}).show();
- },
- afterUpdateInternal: function(effect) {
- effect.element.down().setStyle({bottom:
- (effect.dims[0] - effect.element.clientHeight) + 'px' });
- },
- afterFinishInternal: function(effect) {
- effect.element.undoClipping().undoPositioned();
- effect.element.down().undoPositioned().setStyle({bottom: oldInnerBottom}); }
- }, arguments[1] || { })
- );
-};
-
-Effect.SlideUp = function(element) {
- element = $(element).cleanWhitespace();
- var oldInnerBottom = element.down().getStyle('bottom');
- var elementDimensions = element.getDimensions();
- return new Effect.Scale(element, window.opera ? 0 : 1,
- Object.extend({ scaleContent: false,
- scaleX: false,
- scaleMode: 'box',
- scaleFrom: 100,
- scaleMode: {originalHeight: elementDimensions.height, originalWidth: elementDimensions.width},
- restoreAfterFinish: true,
- afterSetup: function(effect) {
- effect.element.makePositioned();
- effect.element.down().makePositioned();
- if (window.opera) effect.element.setStyle({top: ''});
- effect.element.makeClipping().show();
- },
- afterUpdateInternal: function(effect) {
- effect.element.down().setStyle({bottom:
- (effect.dims[0] - effect.element.clientHeight) + 'px' });
- },
- afterFinishInternal: function(effect) {
- effect.element.hide().undoClipping().undoPositioned();
- effect.element.down().undoPositioned().setStyle({bottom: oldInnerBottom});
- }
- }, arguments[1] || { })
- );
-};
-
-// Bug in opera makes the TD containing this element expand for a instance after finish
-Effect.Squish = function(element) {
- return new Effect.Scale(element, window.opera ? 1 : 0, {
- restoreAfterFinish: true,
- beforeSetup: function(effect) {
- effect.element.makeClipping();
- },
- afterFinishInternal: function(effect) {
- effect.element.hide().undoClipping();
- }
- });
-};
-
-Effect.Grow = function(element) {
- element = $(element);
- var options = Object.extend({
- direction: 'center',
- moveTransition: Effect.Transitions.sinoidal,
- scaleTransition: Effect.Transitions.sinoidal,
- opacityTransition: Effect.Transitions.full
- }, arguments[1] || { });
- var oldStyle = {
- top: element.style.top,
- left: element.style.left,
- height: element.style.height,
- width: element.style.width,
- opacity: element.getInlineOpacity() };
-
- var dims = element.getDimensions();
- var initialMoveX, initialMoveY;
- var moveX, moveY;
-
- switch (options.direction) {
- case 'top-left':
- initialMoveX = initialMoveY = moveX = moveY = 0;
- break;
- case 'top-right':
- initialMoveX = dims.width;
- initialMoveY = moveY = 0;
- moveX = -dims.width;
- break;
- case 'bottom-left':
- initialMoveX = moveX = 0;
- initialMoveY = dims.height;
- moveY = -dims.height;
- break;
- case 'bottom-right':
- initialMoveX = dims.width;
- initialMoveY = dims.height;
- moveX = -dims.width;
- moveY = -dims.height;
- break;
- case 'center':
- initialMoveX = dims.width / 2;
- initialMoveY = dims.height / 2;
- moveX = -dims.width / 2;
- moveY = -dims.height / 2;
- break;
- }
-
- return new Effect.Move(element, {
- x: initialMoveX,
- y: initialMoveY,
- duration: 0.01,
- beforeSetup: function(effect) {
- effect.element.hide().makeClipping().makePositioned();
- },
- afterFinishInternal: function(effect) {
- new Effect.Parallel(
- [ new Effect.Opacity(effect.element, { sync: true, to: 1.0, from: 0.0, transition: options.opacityTransition }),
- new Effect.Move(effect.element, { x: moveX, y: moveY, sync: true, transition: options.moveTransition }),
- new Effect.Scale(effect.element, 100, {
- scaleMode: { originalHeight: dims.height, originalWidth: dims.width },
- sync: true, scaleFrom: window.opera ? 1 : 0, transition: options.scaleTransition, restoreAfterFinish: true})
- ], Object.extend({
- beforeSetup: function(effect) {
- effect.effects[0].element.setStyle({height: '0px'}).show();
- },
- afterFinishInternal: function(effect) {
- effect.effects[0].element.undoClipping().undoPositioned().setStyle(oldStyle);
- }
- }, options)
- );
- }
- });
-};
-
-Effect.Shrink = function(element) {
- element = $(element);
- var options = Object.extend({
- direction: 'center',
- moveTransition: Effect.Transitions.sinoidal,
- scaleTransition: Effect.Transitions.sinoidal,
- opacityTransition: Effect.Transitions.none
- }, arguments[1] || { });
- var oldStyle = {
- top: element.style.top,
- left: element.style.left,
- height: element.style.height,
- width: element.style.width,
- opacity: element.getInlineOpacity() };
-
- var dims = element.getDimensions();
- var moveX, moveY;
-
- switch (options.direction) {
- case 'top-left':
- moveX = moveY = 0;
- break;
- case 'top-right':
- moveX = dims.width;
- moveY = 0;
- break;
- case 'bottom-left':
- moveX = 0;
- moveY = dims.height;
- break;
- case 'bottom-right':
- moveX = dims.width;
- moveY = dims.height;
- break;
- case 'center':
- moveX = dims.width / 2;
- moveY = dims.height / 2;
- break;
- }
-
- return new Effect.Parallel(
- [ new Effect.Opacity(element, { sync: true, to: 0.0, from: 1.0, transition: options.opacityTransition }),
- new Effect.Scale(element, window.opera ? 1 : 0, { sync: true, transition: options.scaleTransition, restoreAfterFinish: true}),
- new Effect.Move(element, { x: moveX, y: moveY, sync: true, transition: options.moveTransition })
- ], Object.extend({
- beforeStartInternal: function(effect) {
- effect.effects[0].element.makePositioned().makeClipping();
- },
- afterFinishInternal: function(effect) {
- effect.effects[0].element.hide().undoClipping().undoPositioned().setStyle(oldStyle); }
- }, options)
- );
-};
-
-Effect.Pulsate = function(element) {
- element = $(element);
- var options = arguments[1] || { },
- oldOpacity = element.getInlineOpacity(),
- transition = options.transition || Effect.Transitions.linear,
- reverser = function(pos){
- return 1 - transition((-Math.cos((pos*(options.pulses||5)*2)*Math.PI)/2) + .5);
- };
-
- return new Effect.Opacity(element,
- Object.extend(Object.extend({ duration: 2.0, from: 0,
- afterFinishInternal: function(effect) { effect.element.setStyle({opacity: oldOpacity}); }
- }, options), {transition: reverser}));
-};
-
-Effect.Fold = function(element) {
- element = $(element);
- var oldStyle = {
- top: element.style.top,
- left: element.style.left,
- width: element.style.width,
- height: element.style.height };
- element.makeClipping();
- return new Effect.Scale(element, 5, Object.extend({
- scaleContent: false,
- scaleX: false,
- afterFinishInternal: function(effect) {
- new Effect.Scale(element, 1, {
- scaleContent: false,
- scaleY: false,
- afterFinishInternal: function(effect) {
- effect.element.hide().undoClipping().setStyle(oldStyle);
- } });
- }}, arguments[1] || { }));
-};
-
-Effect.Morph = Class.create(Effect.Base, {
- initialize: function(element) {
- this.element = $(element);
- if (!this.element) throw(Effect._elementDoesNotExistError);
- var options = Object.extend({
- style: { }
- }, arguments[1] || { });
-
- if (!Object.isString(options.style)) this.style = $H(options.style);
- else {
- if (options.style.include(':'))
- this.style = options.style.parseStyle();
- else {
- this.element.addClassName(options.style);
- this.style = $H(this.element.getStyles());
- this.element.removeClassName(options.style);
- var css = this.element.getStyles();
- this.style = this.style.reject(function(style) {
- return style.value == css[style.key];
- });
- options.afterFinishInternal = function(effect) {
- effect.element.addClassName(effect.options.style);
- effect.transforms.each(function(transform) {
- effect.element.style[transform.style] = '';
- });
- };
- }
- }
- this.start(options);
- },
-
- setup: function(){
- function parseColor(color){
- if (!color || ['rgba(0, 0, 0, 0)','transparent'].include(color)) color = '#ffffff';
- color = color.parseColor();
- return $R(0,2).map(function(i){
- return parseInt( color.slice(i*2+1,i*2+3), 16 );
- });
- }
- this.transforms = this.style.map(function(pair){
- var property = pair[0], value = pair[1], unit = null;
-
- if (value.parseColor('#zzzzzz') != '#zzzzzz') {
- value = value.parseColor();
- unit = 'color';
- } else if (property == 'opacity') {
- value = parseFloat(value);
- if (Prototype.Browser.IE && (!this.element.currentStyle.hasLayout))
- this.element.setStyle({zoom: 1});
- } else if (Element.CSS_LENGTH.test(value)) {
- var components = value.match(/^([\+\-]?[0-9\.]+)(.*)$/);
- value = parseFloat(components[1]);
- unit = (components.length == 3) ? components[2] : null;
- }
-
- var originalValue = this.element.getStyle(property);
- return {
- style: property.camelize(),
- originalValue: unit=='color' ? parseColor(originalValue) : parseFloat(originalValue || 0),
- targetValue: unit=='color' ? parseColor(value) : value,
- unit: unit
- };
- }.bind(this)).reject(function(transform){
- return (
- (transform.originalValue == transform.targetValue) ||
- (
- transform.unit != 'color' &&
- (isNaN(transform.originalValue) || isNaN(transform.targetValue))
- )
- );
- });
- },
- update: function(position) {
- var style = { }, transform, i = this.transforms.length;
- while(i--)
- style[(transform = this.transforms[i]).style] =
- transform.unit=='color' ? '#'+
- (Math.round(transform.originalValue[0]+
- (transform.targetValue[0]-transform.originalValue[0])*position)).toColorPart() +
- (Math.round(transform.originalValue[1]+
- (transform.targetValue[1]-transform.originalValue[1])*position)).toColorPart() +
- (Math.round(transform.originalValue[2]+
- (transform.targetValue[2]-transform.originalValue[2])*position)).toColorPart() :
- (transform.originalValue +
- (transform.targetValue - transform.originalValue) * position).toFixed(3) +
- (transform.unit === null ? '' : transform.unit);
- this.element.setStyle(style, true);
- }
-});
-
-Effect.Transform = Class.create({
- initialize: function(tracks){
- this.tracks = [];
- this.options = arguments[1] || { };
- this.addTracks(tracks);
- },
- addTracks: function(tracks){
- tracks.each(function(track){
- track = $H(track);
- var data = track.values().first();
- this.tracks.push($H({
- ids: track.keys().first(),
- effect: Effect.Morph,
- options: { style: data }
- }));
- }.bind(this));
- return this;
- },
- play: function(){
- return new Effect.Parallel(
- this.tracks.map(function(track){
- var ids = track.get('ids'), effect = track.get('effect'), options = track.get('options');
- var elements = [$(ids) || $$(ids)].flatten();
- return elements.map(function(e){ return new effect(e, Object.extend({ sync:true }, options)) });
- }).flatten(),
- this.options
- );
- }
-});
-
-Element.CSS_PROPERTIES = $w(
- 'backgroundColor backgroundPosition borderBottomColor borderBottomStyle ' +
- 'borderBottomWidth borderLeftColor borderLeftStyle borderLeftWidth ' +
- 'borderRightColor borderRightStyle borderRightWidth borderSpacing ' +
- 'borderTopColor borderTopStyle borderTopWidth bottom clip color ' +
- 'fontSize fontWeight height left letterSpacing lineHeight ' +
- 'marginBottom marginLeft marginRight marginTop markerOffset maxHeight '+
- 'maxWidth minHeight minWidth opacity outlineColor outlineOffset ' +
- 'outlineWidth paddingBottom paddingLeft paddingRight paddingTop ' +
- 'right textIndent top width wordSpacing zIndex');
-
-Element.CSS_LENGTH = /^(([\+\-]?[0-9\.]+)(em|ex|px|in|cm|mm|pt|pc|\%))|0$/;
-
-String.__parseStyleElement = document.createElement('div');
-String.prototype.parseStyle = function(){
- var style, styleRules = $H();
- if (Prototype.Browser.WebKit)
- style = new Element('div',{style:this}).style;
- else {
- String.__parseStyleElement.innerHTML = '<div style="' + this + '"></div>';
- style = String.__parseStyleElement.childNodes[0].style;
- }
-
- Element.CSS_PROPERTIES.each(function(property){
- if (style[property]) styleRules.set(property, style[property]);
- });
-
- if (Prototype.Browser.IE && this.include('opacity'))
- styleRules.set('opacity', this.match(/opacity:\s*((?:0|1)?(?:\.\d*)?)/)[1]);
-
- return styleRules;
-};
-
-if (document.defaultView && document.defaultView.getComputedStyle) {
- Element.getStyles = function(element) {
- var css = document.defaultView.getComputedStyle($(element), null);
- return Element.CSS_PROPERTIES.inject({ }, function(styles, property) {
- styles[property] = css[property];
- return styles;
- });
- };
-} else {
- Element.getStyles = function(element) {
- element = $(element);
- var css = element.currentStyle, styles;
- styles = Element.CSS_PROPERTIES.inject({ }, function(results, property) {
- results[property] = css[property];
- return results;
- });
- if (!styles.opacity) styles.opacity = element.getOpacity();
- return styles;
- };
-}
-
-Effect.Methods = {
- morph: function(element, style) {
- element = $(element);
- new Effect.Morph(element, Object.extend({ style: style }, arguments[2] || { }));
- return element;
- },
- visualEffect: function(element, effect, options) {
- element = $(element);
- var s = effect.dasherize().camelize(), klass = s.charAt(0).toUpperCase() + s.substring(1);
- new Effect[klass](element, options);
- return element;
- },
- highlight: function(element, options) {
- element = $(element);
- new Effect.Highlight(element, options);
- return element;
- }
-};
-
-$w('fade appear grow shrink fold blindUp blindDown slideUp slideDown '+
- 'pulsate shake puff squish switchOff dropOut').each(
- function(effect) {
- Effect.Methods[effect] = function(element, options){
- element = $(element);
- Effect[effect.charAt(0).toUpperCase() + effect.substring(1)](element, options);
- return element;
- };
- }
-);
-
-$w('getInlineOpacity forceRerendering setContentZoom collectTextNodes collectTextNodesIgnoreClass getStyles').each(
- function(f) { Effect.Methods[f] = Element[f]; }
-);
-
-Element.addMethods(Effect.Methods); \ No newline at end of file
diff --git a/lib/scriptaculous/scriptaculous.js b/lib/scriptaculous/scriptaculous.js
deleted file mode 100644
index 0ea5c4457..000000000
--- a/lib/scriptaculous/scriptaculous.js
+++ /dev/null
@@ -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(); \ No newline at end of file
diff --git a/plugins/af_readability/init.js b/plugins/af_readability/init.js
index ff2d94e8b..6dec82f45 100644
--- a/plugins/af_readability/init.js
+++ b/plugins/af_readability/init.js
@@ -2,8 +2,8 @@ Plugins.Af_Readability = {
orig_attr_name: 'data-readability-orig-content',
self: this,
embed: function(id) {
- const content = $$(App.isCombinedMode() ? ".cdm[data-article-id=" + id + "] .content-inner" :
- ".post[data-article-id=" + id + "] .content")[0];
+ const content = App.find(App.isCombinedMode() ? ".cdm[data-article-id=" + id + "] .content-inner" :
+ ".post[data-article-id=" + id + "] .content");
if (content.hasAttribute(self.orig_attr_name)) {
content.innerHTML = content.getAttribute(self.orig_attr_name);
diff --git a/plugins/af_zz_vidmute/init.js b/plugins/af_zz_vidmute/init.js
index fab9b99e6..b8be8cecd 100644
--- a/plugins/af_zz_vidmute/init.js
+++ b/plugins/af_zz_vidmute/init.js
@@ -3,7 +3,7 @@ require(['dojo/_base/kernel', 'dojo/ready'], function (dojo, ready) {
PluginHost.register(PluginHost.HOOK_ARTICLE_RENDERED_CDM, function (row) {
if (row) {
- row.select("video").each(function (v) {
+ row.querySelectorAll("video").forEach(function (v) {
v.muted = true;
});
}
@@ -14,7 +14,7 @@ require(['dojo/_base/kernel', 'dojo/ready'], function (dojo, ready) {
PluginHost.register(PluginHost.HOOK_ARTICLE_RENDERED, function (row) {
if (row) {
- row.select("video").each(function (v) {
+ row.querySelectorAll("video").forEach(function (v) {
v.muted = true;
});
}
diff --git a/plugins/share/share.js b/plugins/share/share.js
index 46b62ca5b..a5f60d267 100644
--- a/plugins/share/share.js
+++ b/plugins/share/share.js
@@ -23,9 +23,6 @@ Plugins.Share = {
target.href = target.href.replace(/&key=.*$/,
"&key=" + new_link);
- // eslint-disable-next-line no-new
- new Effect.Highlight(target);
-
const icon = document.querySelector(".share-icon-" + id);
if (icon)
diff --git a/plugins/shorten_expanded/init.js b/plugins/shorten_expanded/init.js
index 873749c03..0abc8c129 100644
--- a/plugins/shorten_expanded/init.js
+++ b/plugins/shorten_expanded/init.js
@@ -7,8 +7,8 @@ Plugins.Shorten_Expanded = {
const row = $(id);
if (row) {
- const content = row.select(".content-shrink-wrap")[0];
- const link = row.select(".expand-prompt")[0];
+ const content = row.querySelector(".content-shrink-wrap");
+ const link = row.querySelector(".expand-prompt");
if (content) content.removeClassName("content-shrink-wrap");
if (link) Element.hide(link);
diff --git a/prefs.php b/prefs.php
index 9d5f8e499..71dc73b29 100644
--- a/prefs.php
+++ b/prefs.php
@@ -59,8 +59,7 @@
</script>
<?php
- foreach (array("lib/prototype.js",
- "lib/scriptaculous/scriptaculous.js?load=effects,controls",
+ foreach (array(#"lib/prototype.js",
"lib/dojo/dojo.js",
"lib/dojo/tt-rss-layer.js",
"js/common.js",