|
|
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
|
|
|
"http://www.w3.org/TR/html4/loose.dtd">
|
|
|
<html>
|
|
|
<head>
|
|
|
<title></title>
|
|
|
<!-- 这里页面标题为空,通常可设置一个有意义的标题,用于在浏览器标题栏展示页面相关信息 -->
|
|
|
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
|
|
|
<!-- 通过 HTTP 头部等价属性(http-equiv)设置页面内容类型为 HTML 文本格式,字符编码为 UTF-8,确保页面能正确显示各种字符 -->
|
|
|
<script type="text/javascript" src="../internal.js"></script>
|
|
|
<!-- 引入相对路径为“../internal.js”的 JavaScript 文件,该文件可能包含页面会用到的自定义函数、变量以及通用业务逻辑等代码,具体功能依赖其内部定义 -->
|
|
|
<style type="text/css">
|
|
|
* {
|
|
|
margin: 0;
|
|
|
padding: 0;
|
|
|
color: #838383;
|
|
|
}
|
|
|
/* 通配符选择器(*)设置所有元素的外边距(margin)和内边距(padding)为 0,文本颜色为浅灰色(#838383),用于统一页面元素的基本样式布局和文字颜色风格 */
|
|
|
table {
|
|
|
font-size: 12px;
|
|
|
margin: 10px;
|
|
|
line-height: 30px;
|
|
|
}
|
|
|
/* 针对 table 元素设置字体大小为 12 像素,外边距为 10 像素(在页面中与周围元素留出一定间隔),行高为 30 像素,控制表格内文本的显示样式和整体布局位置 */
|
|
|
.txt {
|
|
|
width: 300px;
|
|
|
height: 21px;
|
|
|
line-height: 21px;
|
|
|
border: 1px solid #d7d7d7;
|
|
|
}
|
|
|
/* 定义类名为 'txt' 的元素样式,设置宽度为 300 像素,高度为 21 像素,行高与高度相同(使文本垂直居中),边框为 1 像素宽的浅灰色(#d7d7d7)实线,用于具有此类名的输入框等元素呈现统一的外观样式 */
|
|
|
</style>
|
|
|
</head>
|
|
|
<body>
|
|
|
<table>
|
|
|
<!-- 创建一个表格元素,用于以表格形式布局页面内相关输入框、文本标签等元素 -->
|
|
|
<tr>
|
|
|
<td><label for="text"> <var id="lang_input_text"></var></label></td>
|
|
|
<td><input class="txt" id="text" type="text" disabled="true" /></td>
|
|
|
</tr>
|
|
|
<!-- 创建表格的一行(tr),该行包含两个单元格(td)。第一个单元格放置一个 label 标签,通过 'for' 属性关联到后面 id 为 'text' 的输入框元素,label 内部嵌套一个带有特定 id 的 var 元素,其文本内容可能通过 JavaScript 动态设置,推测用于显示与文本相关的提示信息;第二个单元格放置一个 id 为 'text'、类名为 'txt' 的文本输入框元素,并且初始设置为禁用状态(disabled="true") -->
|
|
|
<tr>
|
|
|
<td><label for="href"> <var id="lang_input_url"></var></label></td>
|
|
|
<td><input class="txt" id="href" type="text" /></td>
|
|
|
</tr>
|
|
|
<!-- 与上一行结构类似,这行的 label 元素通过 'for' 属性关联到 id 为 'href' 的输入框,var 元素文本用于显示与网址(url)相关的提示信息,后面的输入框(id 为 'href')用于用户输入网址,且未设置禁用状态 -->
|
|
|
<tr>
|
|
|
<td><label for="title"> <var id="lang_input_title"></var></label></td>
|
|
|
<td><input class="txt" id="title" type="text" /></td>
|
|
|
</tr>
|
|
|
<!-- 同样结构的一行,label 关联到 id 为 'title' 的输入框,var 元素提示与标题相关信息,输入框用于输入标题内容 -->
|
|
|
<tr>
|
|
|
<td colspan="2">
|
|
|
<label for="target"><var id="lang_input_target"></var></label>
|
|
|
<input id="target" type="checkbox" />
|
|
|
</td>
|
|
|
</tr>
|
|
|
<!-- 这行两个单元格合并(colspan="2"),放置一个 label 元素通过 'for' 属性关联到后面的复选框(checkbox)元素,var 元素提示与目标(可能是链接打开的目标窗口等相关)信息,复选框用于用户勾选相关选项,具体功能看后续 JavaScript 代码逻辑 -->
|
|
|
<tr>
|
|
|
<td colspan="2" id="msg"></td>
|
|
|
</tr>
|
|
|
<!-- 又是两个单元格合并的一行,包含一个 id 为'msg' 的空单元格,从后续 JavaScript 代码可知,该单元格用于显示一些提示信息(如网址格式相关提示等) -->
|
|
|
</table>
|
|
|
|
|
|
<script type="text/javascript">
|
|
|
|
|
|
editor.setOpt('allowLinkProtocols', ['http:', 'https:', '#', '/', 'ftp:', 'mailto:', 'tel:']);
|
|
|
// 通过编辑器(editor,可能是富文本编辑器相关对象,具体依赖代码上下文环境)的 setOpt 方法设置一个名为 'allowLinkProtocols' 的选项,其值为一个包含多种协议(如 'http:'、'https:' 等)的数组,用于限定允许的链接协议类型,后续会根据此进行链接网址合法性校验等操作。
|
|
|
var allowLinkProtocols = editor.getOpt('allowLinkProtocols');
|
|
|
// 获取编辑器中设置的 'allowLinkProtocols' 选项的值,存储在 allowLinkProtocols 变量中,方便后续代码多次使用该允许的协议列表进行判断。
|
|
|
|
|
|
var range = editor.selection.getRange(),
|
|
|
link = range.collapsed ? editor.queryCommandValue("link") : editor.selection.getStart(),
|
|
|
url,
|
|
|
text = $G('text'),
|
|
|
rangeLink = domUtils.findParentByTagName(range.getCommonAncestor(), 'a', true),
|
|
|
orgText;
|
|
|
// 获取编辑器当前选区的范围(通过 editor.selection.getRange() 方法)存储在 range 变量中;根据选区是否折叠(collapsed 属性)来决定获取不同的链接相关信息,如果选区折叠,通过 editor.queryCommandValue("link") 获取链接相关的值(具体含义看编辑器对应命令实现),否则获取选区开始位置(editor.selection.getStart())作为 link 值;声明 url 变量(初始未赋值,后续用于存储链接网址等信息);通过 $G 函数(可能是自定义的获取 DOM 元素的函数)获取页面中 id 为 'text' 的元素存储在 text 变量中;通过 domUtils.findParentByTagName 函数(可能是自定义的根据标签名查找父元素的函数)查找选区共同祖先元素中最近的 'a' 标签元素(链接元素),并将结果存储在 rangeLink 变量中;声明 orgText 变量(初始未赋值,后续用于存储原始文本等相关信息)。
|
|
|
|
|
|
link = domUtils.findParentByTagName(link, "a", true);
|
|
|
// 再次调用 domUtils.findParentByTagName 函数,对之前获取的 link 值(可能是元素或相关对象)进一步查找其最近的 'a' 标签父元素,更新 link 变量,确保获取到准确的链接元素(如果存在的话),用于后续对链接相关属性的操作。
|
|
|
|
|
|
if (link) {
|
|
|
url = utils.html(link.getAttribute('_href') || link.getAttribute('href', 2));
|
|
|
// 如果找到了链接元素(link 存在),通过 utils.html 函数(可能是自定义的处理 HTML 相关属性值的函数)获取链接元素的 '_href' 属性值(可能是自定义属性用于存储链接网址等情况),如果不存在则获取 'href' 属性值(标准的链接网址属性),将获取到的值存储在 url 变量中,用于后续操作。
|
|
|
|
|
|
if (rangeLink === link && !link.getElementsByTagName('img').length) {
|
|
|
text.removeAttribute('disabled');
|
|
|
orgText = text.value = link[browser.ie ? 'innerText' : 'textContent'];
|
|
|
} else {
|
|
|
text.setAttribute('disabled', 'true');
|
|
|
text.value = lang.validLink;
|
|
|
}
|
|
|
// 判断如果之前获取的 rangeLink(选区对应的链接元素)与当前的 link(找到的链接元素)是同一个,并且链接元素内部不包含图片元素(通过 getElementsByTagName 方法判断 'img' 元素数量为 0),则将页面中 id 为 'text' 的输入框元素的 'disabled' 属性移除(即启用该输入框),并将链接元素的文本内容(根据浏览器类型,通过 'innerText' 或 'textContent' 属性获取)赋值给输入框的 value 属性,同时存储该原始文本内容到 orgText 变量中;否则(不符合上述条件),将输入框设置为禁用状态,并设置其 value 属性为 lang.validLink(可能是通过语言包获取的提示文本,用于显示在输入框中表示当前链接相关的某种特定状态)。
|
|
|
|
|
|
} else {
|
|
|
if (range.collapsed) {
|
|
|
text.removeAttribute('disabled');
|
|
|
text.value = '';
|
|
|
} else {
|
|
|
text.setAttribute('disabled', 'true');
|
|
|
text.value = lang.validLink;
|
|
|
}
|
|
|
// 如果没有找到链接元素(link 不存在),再根据选区是否折叠进行不同操作。如果选区折叠,启用页面中 id 为 'text' 的输入框(移除 'disabled' 属性)并将其 value 属性设置为空字符串;如果选区未折叠,则禁用该输入框,并将其 value 属性设置为 lang.validLink(提示文本)。
|
|
|
}
|
|
|
$G("title").value = url ? link.title : "";
|
|
|
$G("href").value = url ? url : '';
|
|
|
$G("target").checked = url && link.target == "_blank" ? true : false;
|
|
|
$focus($G("href"));
|
|
|
// 通过 $G 函数分别获取页面中 id 为 'title'、'href' 和 'target' 的元素,并根据前面获取到的 url 值以及链接元素(link)的相关属性进行赋值操作。如果 url 存在,将链接元素的 'title' 属性值赋给 id 为 'title' 的输入框的 value 属性,将 url 值赋给 id 为 'href' 的输入框的 value 属性;根据 url 是否存在以及链接元素的 'target' 属性是否为 '_blank' 来设置 id 为 'target' 的复选框的选中状态(checked 属性);最后通过 $focus 函数(可能是自定义的设置焦点的函数)将焦点设置到 id 为 'href' 的输入框上,方便用户输入操作。
|
|
|
|
|
|
function handleDialogOk() {
|
|
|
var href = $G('href').value.replace(/^\s+|\s+$/g, '');
|
|
|
// 定义一个名为 'handleDialogOk' 的函数,在函数内部首先获取页面中 id 为 'href' 的输入框元素去除首尾空白字符后的文本值(通过正则表达式替换空白字符),存储在 href 变量中,用于后续对输入的网址进行合法性校验等操作。
|
|
|
if (href) {
|
|
|
if (!hrefStartWith(href, allowLinkProtocols)) {
|
|
|
href = "http://" + href;
|
|
|
}
|
|
|
// 如果获取到的 href 值不为空,调用 hrefStartWith 函数(后续定义)判断输入的网址是否以允许的链接协议(allowLinkProtocols 中定义的协议)开头,如果不满足,则在网址前面拼接 'http://',确保网址格式符合限定的协议要求。
|
|
|
|
|
|
var obj = {
|
|
|
'href': href,
|
|
|
'target': $G("target").checked ? "_blank" : '_self',
|
|
|
'title': $G("title").value.replace(/^\s+|\s+$/g, ''),
|
|
|
'_href': href
|
|
|
};
|
|
|
// 创建一个包含多个属性的对象 obj,用于存储链接相关的信息,其中 'href' 属性为经过处理后的网址,'target' 属性根据页面中 id 为 'target' 的复选框的选中状态来确定是 '_blank'(新窗口打开)还是 '_self'(在当前窗口打开),'title' 属性为去除首尾空白字符后的 id 为 'title' 的输入框的 value 值,'_href' 属性与 'href' 属性相同(可能用于特定的编辑器内部处理等情况)。
|
|
|
|
|
|
// 修改链接内容的情况太特殊了,所以先做到这里了
|
|
|
// todo:情况多的时候,做到command里
|
|
|
if (orgText && text.value != orgText) {
|
|
|
link[browser.ie ? 'innerText' : 'textContent'] = obj.textValue = text.value;
|
|
|
range.selectNode(link).select();
|
|
|
}
|
|
|
// 如果 orgText 存在(即之前有原始文本记录)并且页面中 id 为 'text' 的输入框当前值与原始文本不同,表示用户修改了链接的文本内容,根据浏览器类型(通过 browser.ie 判断是否为 IE 浏览器)将输入框的当前值设置为链接元素的文本内容(通过 'innerText' 或 'textContent' 属性),同时将输入框的值也赋给 obj 对象的 textValue 属性(可能用于后续统一传递数据等情况),然后通过选区范围(range)的 selectNode 和 select 方法重新选中该链接元素,使编辑后的链接文本在编辑器中处于选中状态,方便用户查看效果等。
|
|
|
|
|
|
if (range.collapsed) {
|
|
|
obj.textValue = text.value;
|
|
|
}
|
|
|
// 如果选区是折叠状态,将页面中 id 为 'text' 的输入框的值赋给 obj 对象的 textValue 属性,可能用于在这种特殊情况下也传递相关文本信息到后续操作中。
|
|
|
|
|
|
editor.execCommand('link', utils.clearEmptyAttrs(obj));
|
|
|
dialog.close();
|
|
|
// 通过编辑器的 execCommand 方法执行 'link' 命令(具体功能依赖编辑器对该命令的实现),并传入经过 utils.clearEmptyAttrs 函数(可能是自定义的清除对象空属性的函数)处理后的 obj 对象作为参数,用于根据用户输入和设置更新链接相关属性等操作,最后关闭对话框(dialog,可能是页面上弹出用于操作链接的对话框,具体关闭操作依赖 dialog 对象的实现),完成整个链接编辑操作流程。
|
|
|
}
|
|
|
}
|
|
|
dialog.onok = handleDialogOk;
|
|
|
// 将对话框(dialog)的 'onok' 事件(可能表示用户点击确定按钮的事件)绑定到 'handleDialogOk' 函数上,当用户在对话框中点击确定按钮时,就会执行 'handleDialogOk' 函数内的一系列操作,实现相应的链接编辑及保存等功能逻辑。
|
|
|
|
|
|
$G('href').onkeydown = $G('title').onkeydown = function (evt) {
|
|
|
evt = evt || window.event;
|
|
|
if (evt.keyCode == 13) {
|
|
|
handleDialogOk();
|
|
|
return false;
|
|
|
}
|
|
|
};
|
|
|
// 同时为页面中 id 为 'href' 和 'title' 的输入框元素绑定 'onkeydown' 键盘按下事件监听器,当有键盘按键按下时,首先处理不同浏览器获取事件对象的兼容性问题(evt = evt || window.event,兼容 IE 和其他标准浏览器获取事件对象的方式),然后判断按下的按键的键码(keyCode)是否为 13(回车键的键码),如果是回车键按下,则调用 'handleDialogOk' 函数,实现用户在这两个输入框中按下回车键时等同于点击确定按钮的功能,方便用户操作,并且返回 false 阻止默认的回车键行为(比如表单提交等默认行为)。
|
|
|
|
|
|
$G('href').onblur = function () {
|
|
|
if (!hrefStartWith(this.value, allowLinkProtocols)) {
|
|
|
$G("msg").innerHTML = "<span style='color: red'>" + lang.httpPrompt + "</span>";
|
|
|
} else {
|
|
|
$G("msg").innerHTML = "";
|
|
|
}
|
|
|
};
|
|
|
// 为页面中 id 为 'href' 的输入框元素绑定 'onblur' 失去焦点事件监听器,当输入框失去焦点时,调用 hrefStartWith 函数判断当前输入框的值(通过 this.value 获取)是否以允许的链接协议开头,如果不满足,则将页面中 id 为'msg' 的元素的 innerHTML 属性设置为一个包含红色字体提示文本(lang.httpPrompt,可能是通过语言包获取的提示网址格式错误等相关信息)的 span 元素代码,用于在页面上显示错误提示;如果满足协议要求,则清空'msg' 元素的 innerHTML,即清除提示信息。
|
|
|
|
|
|
function hrefStartWith(href, arr) {
|
|
|
href = href.replace(/^\s+|\s+$/g, '');
|
|
|
for (var i = 0, ai; ai = arr[i++];) {
|
|
|
if (href.indexOf(ai) == 0) {
|
|
|
return true;
|
|
|
}
|
|
|
}
|
|
|
return false;
|
|
|
}
|
|
|
// 定义一个名为 'hrefStartWith' 的函数,用于判断输入的网址(href 参数)是否以给定数组(arr 参数,可能是允许的链接协议数组)中的某个协议开头。函数内部首先去除网址的首尾空白字符,然后循环遍历数组中的每个协议元素,通过 indexOf 方法判断网址是否以该协议开头,如果找到匹配的协议开头则返回 true,循环结束后都未找到匹配则返回 false,用于网址合法性校验相关操作,判断网址格式是否符合限定的协议要求。
|
|
|
</script>
|
|
|
|
|
|
</script>
|
|
|
</body>
|
|
|
</html>
|