-
-
-
-
-
-
+//输出面板效果
+?>
+
+参数间用%s号隔开, 支持%s(自动播放)%s(循环播放)%s(曲名)%s(艺术家名)等. 示例','[mp3]','[/mp3]',',','|','autostart','loop','titles','artists'); ?>
+
+
+[mp3]http://dfp.mp3,http://m.mp3|
+titles=东风破,The Monster|
+artists=周杰伦,Eminem|
+autostart=no|
+loop=yes[/mp3]
+
+
+
+
+
+
+
+
+
+
+
+
-input->setAttribute('class','w-10');
- $ap_width->addRule(array(new AudioPlayer_Plugin,'widthformat'),_t('请输入整数或百分数'));
- $ap_width->addRule('required',_t('播放器宽度不能为空'));
- $form->addInput($ap_width);
+
- $ap_fieldselector= new Typecho_Widget_Helper_Form_Element_Select('ap_fieldselector',
+_t('背景'),
'leftbg'=>_t('左侧背景'),
- 'lefticon'=>_t('左侧图标(喇叭)'),
+ 'lefticon'=>_t('左侧图标'),
'voltrack'=>_t('音量背景'),
'volslider'=>_t('音量滑块'),
'rightbg'=>_t('右侧背景'),
- 'rightbghover'=>_t('右侧背景(悬停时)'),
- 'righticon'=>_t('右侧图标(播放/暂停)'),
- 'righticonhover'=>_t('右侧图标(悬停时)'),
- 'text'=>_t('文本'),'tracker'=>_t('进度条'),
+ 'rightbghover'=>_t('右侧背景(悬停)'),
+ 'righticon'=>_t('右侧图标'),
+ 'righticonhover'=>_t('右侧图标(悬停)'),
+ 'text'=>_t('文本'),
+ 'tracker'=>_t('进度条'),
'track'=>_t('进度条(剩余)'),
'border'=>_t('进度条(边框)'),
'loader'=>_t('加载条'),
'skip'=>_t('切歌按钮')
),
- 'bg',_t('配色方案'),'
+ 'bg',_t('播放器配色'),'
Audio Player
- ');
$ap_fieldselector->input->setAttribute('id','ap_fieldselector');
- $ap_fieldselector->input->setAttribute('style','height:23px;');
+ $ap_fieldselector->input->setAttribute('style','height:23px');
$form->addInput($ap_fieldselector);
- $ap_behaviour = new Typecho_Widget_Helper_Form_Element_Checkbox('ap_behaviour',
- array('1'=>_t('将文章内地址为mp3的链接替换成播放器')),NULL,_t('替换mp3链接'));
- $form->addInput($ap_behaviour);
+ if (Typecho_Request::getInstance()->is('action=resetcolor') && isset($options->plugins['activated']['AudioPlayer'])) {
+ Helper::configPlugin('AudioPlayer',array('ap_colors'=>$colors));
+ Typecho_Response::getInstance()->goBack();
+ }
+ //重置动作按钮
+ $resetcolor = new Typecho_Widget_Helper_Form_Element_Submit();
+ $resetcolor->value(_t('重置'));
+ $resetcolor->setAttribute('style','position:relative');
+ $resetcolor->input->setAttribute('id','ap_resetcolor');
+ $resetcolor->input->setAttribute('class','btn btn-xs');
+ $resetcolor->input->setAttribute('formaction',Helper::security()->getAdminUrl('options-plugin.php?config=AudioPlayer&action=resetcolor'));
+ $form->addItem($resetcolor);
- $ap_encode = new Typecho_Widget_Helper_Form_Element_Checkbox('ap_encode',
- array('1'=>_t('对非法下载或盗链行为起到一定防范作用')),NULL,_t('加密mp3地址'));
- $form->addInput($ap_encode);
+ $ap_width = new Typecho_Widget_Helper_Form_Element_Text('ap_width',
+ NULL,'290',_t('播放器宽度'),_t('输入像素值(如200不用带px)或百分数(如80%)'));
+ $ap_width->input->setAttribute('style','width:50px');
+ $ap_width->addRule(array(new AudioPlayer_Plugin,'widthformat'),_t('请填写整数或百分数'));
+ $ap_width->addRule('required',_t('播放器宽度不能为空'));
+ $form->addInput($ap_width);
+
+ $ap_initialvolume = new Typecho_Widget_Helper_Form_Element_Text('ap_initialvolume',
+ NULL,'60',_t('初始音量大小'),_t('播放器启动时的音量起步值, 最大100, 默认60'));
+ $ap_initialvolume->input->setAttribute('style','width:50px');
+ $ap_initialvolume->addRule('isInteger',_t('请填写整数数字'));
+ $ap_initialvolume->addRule('required',_t('初始音量不能为空'));
+ $form->addInput($ap_initialvolume);
+
+ $ap_buffer = new Typecho_Widget_Helper_Form_Element_Text('ap_buffer',
+ NULL,'5',_t('缓冲等待时间'),_t('单位秒(不用填写), 视播放卡顿情况可适当提高'));
+ $ap_buffer->input->setAttribute('style','width:50px');
+ $ap_buffer->addRule('isInteger',_t('请填写整数数字'));
+ $ap_buffer->addRule('required',_t('缓冲时间不能为空'));
+ $form->addInput($ap_buffer);
$ap_animation = new Typecho_Widget_Helper_Form_Element_Checkbox('ap_animation',
- array('1'=>_t('省去点击动作让播放器直接处于展开状态')),NULL,_t('禁用动画效果'));
+ array(1=>_t('省去点击操作让播放器直接处于展开状态')),NULL,_t('禁用动画效果'));
$form->addInput($ap_animation);
+ $ap_encode = new Typecho_Widget_Helper_Form_Element_Checkbox('ap_encode',
+ array(1=>_t('隐藏文件真实url(不支持HTML5缺省播放)')),NULL,_t('加密mp3地址'));
+ $form->addInput($ap_encode);
+
+ $ap_behaviour = new Typecho_Widget_Helper_Form_Element_Checkbox('ap_behaviour',
+ array(1=>_t('将文内指向mp3的链接自动替换成播放器')),NULL,_t('代替mp3链接'));
+ $form->addInput($ap_behaviour);
+
$ap_remaining = new Typecho_Widget_Helper_Form_Element_Checkbox('ap_remaining',
- array('1'=>_t('显示音频的剩余时长而不是已经播放时长')),NULL,_t('显示剩余时长'));
+ array(1=>_t('显示音频的剩余倒计时而非已播放的时长')),NULL,_t('显示剩余时长'));
$form->addInput($ap_remaining);
- $ap_checkpolicy = new Typecho_Widget_Helper_Form_Element_Checkbox('ap_checkpolicy',
- array('1'=>_t('检查mp3所在服务器是否允许读取
ID3标签')),'1',_t('探测跨域许可'));
- $form->addInput($ap_checkpolicy);
-
$ap_noinfo = new Typecho_Widget_Helper_Form_Element_Checkbox('ap_noinfo',
- array('1'=>_t('即使有也不显示曲名/艺术家名等标签信息')),NULL,_t('禁用曲目信息'));
+ array(1=>_t('隐藏曲名/艺术家名等标签信息仅显示空白')),NULL,_t('禁用曲目信息'));
$form->addInput($ap_noinfo);
- //配色参数隐藏域
- $filtformat = array(new AudioPlayer_Plugin,'colorformat');
- $ap_bgcolor = new Typecho_Widget_Helper_Form_Element_Hidden('ap_bgcolor',NULL,'#E5E5E5',NULL);
- $ap_bgcolor->input->setAttribute('id','ap_bgcolor');
- $form->addInput($ap_bgcolor->addRule($filtformat));
- $ap_leftbgcolor = new Typecho_Widget_Helper_Form_Element_Hidden('ap_leftbgcolor',NULL,'#CCCCCC',NULL);
- $ap_leftbgcolor->input->setAttribute('id','ap_leftbgcolor');
- $form->addInput($ap_leftbgcolor->addRule($filtformat));
- $ap_lefticoncolor = new Typecho_Widget_Helper_Form_Element_Hidden('ap_lefticoncolor',NULL,'#333333',NULL);
- $ap_lefticoncolor->input->setAttribute('id','ap_lefticoncolor');
- $form->addInput($ap_lefticoncolor->addRule($filtformat));
- $ap_voltrackcolor = new Typecho_Widget_Helper_Form_Element_Hidden('ap_voltrackcolor',NULL,'#FFFFFF',NULL);
- $ap_voltrackcolor->input->setAttribute('id','ap_voltrackcolor');
- $form->addInput($ap_voltrackcolor->addRule($filtformat));
- $ap_volslidercolor = new Typecho_Widget_Helper_Form_Element_Hidden('ap_volslidercolor',NULL,'#666666',NULL);
- $ap_volslidercolor->input->setAttribute('id','ap_volslidercolor');
- $form->addInput($ap_volslidercolor->addRule($filtformat));
- $ap_rightbgcolor = new Typecho_Widget_Helper_Form_Element_Hidden('ap_rightbgcolor',NULL,'#B4B4B4',NULL);
- $ap_rightbgcolor->input->setAttribute('id','ap_rightbgcolor');
- $form->addInput($ap_rightbgcolor->addRule($filtformat));
- $ap_rightbghovercolor = new Typecho_Widget_Helper_Form_Element_Hidden('ap_rightbghovercolor',NULL,'#999999',NULL);
- $ap_rightbghovercolor->input->setAttribute('id','ap_rightbghovercolor');
- $form->addInput($ap_rightbghovercolor->addRule($filtformat));
- $ap_righticoncolor = new Typecho_Widget_Helper_Form_Element_Hidden('ap_righticoncolor',NULL,'#333333',NULL);
- $ap_righticoncolor->input->setAttribute('id','ap_righticoncolor');
- $form->addInput($ap_righticoncolor->addRule($filtformat));
- $ap_textcolor = new Typecho_Widget_Helper_Form_Element_Hidden('ap_textcolor',NULL,'#333333',NULL);
- $ap_textcolor->input->setAttribute('id','ap_textcolor');
- $form->addInput($ap_textcolor->addRule($filtformat));
- $ap_trackercolor = new Typecho_Widget_Helper_Form_Element_Hidden('ap_trackercolor',NULL,'#DDDDDD',NULL);
- $ap_trackercolor->input->setAttribute('id','ap_trackercolor');
- $form->addInput($ap_trackercolor->addRule($filtformat));
- $ap_righticonhovercolor = new Typecho_Widget_Helper_Form_Element_Hidden('ap_righticonhovercolor',NULL,'#FFFFFF',NULL);
- $ap_righticonhovercolor->input->setAttribute('id','ap_righticonhovercolor');
- $form->addInput($ap_righticonhovercolor->addRule($filtformat));
- $ap_trackcolor = new Typecho_Widget_Helper_Form_Element_Hidden('ap_trackcolor',NULL,'#FFFFFF',NULL);
- $ap_trackcolor->input->setAttribute('id','ap_trackcolor');
- $form->addInput($ap_trackcolor->addRule($filtformat));
- $ap_bordercolor = new Typecho_Widget_Helper_Form_Element_Hidden('ap_bordercolor',NULL,'#CCCCCC',NULL);
- $ap_bordercolor->input->setAttribute('id','ap_bordercolor');
- $form->addInput($ap_bordercolor->addRule($filtformat));
- $ap_loadercolor = new Typecho_Widget_Helper_Form_Element_Hidden('ap_loadercolor',NULL,'#009900',NULL);
- $ap_loadercolor->input->setAttribute('id','ap_loadercolor');
- $form->addInput($ap_loadercolor->addRule($filtformat));
- $ap_skipcolor = new Typecho_Widget_Helper_Form_Element_Hidden('ap_skipcolor',NULL,'#666666',NULL);
- $ap_skipcolor->input->setAttribute('id','ap_skipcolor');
- $form->addInput($ap_skipcolor->addRule($filtformat));
+ $ap_html5 = new Typecho_Widget_Helper_Form_Element_Checkbox('ap_html5',
+ array(1=>_t('若浏览器不支持flash则显示HTML5播放器')),1,_t('使用缺省播放'));
+ $form->addInput($ap_html5);
+
+ //配色保存隐藏域
+ $ap_colors = new Typecho_Widget_Helper_Form_Element_Hidden('ap_colors',NULL,$colors,NULL);
+ $ap_colors->input->setAttribute('id','ap_colors');
+ $form->addInput($ap_colors);
}
+
/**
* 个人用户的配置面板
*
@@ -200,195 +255,189 @@ public static function config(Typecho_Widget_Helper_Form $form)
public static function personalConfig(Typecho_Widget_Helper_Form $form){}
/**
- * 标签链接替换
+ * 内容标签替换
*
* @param string $content
* @return string
*/
public static function playerparse($content,$widget,$lastResult)
{
- $content = empty($lastResult)?$content:$lastResult;
- $settings = Helper::options()->plugin('AudioPlayer');
+ $content = empty($lastResult) ? $content : $lastResult;
+
+ if ($widget instanceof Widget_Archive && !$widget->request->feed && false!==stripos($content,'[mp3]')) {
+ $pattern = '/\[(mp3)](.*?)\[\/\\1]/si';
+ $callback = array('AudioPlayer_Plugin','parseCallback');
+
+ //替换播放器标签
+ $content = preg_replace_callback($pattern,$callback,$content);
- if ($widget instanceof Widget_Archive) {
//替换mp3链接
- if ($settings->ap_behaviour) {
- $pattern = "/
([^<]+)<\/a>/is";
- $content = preg_replace_callback($pattern,array('AudioPlayer_Plugin',"parseCallback"),$content);
+ if (Helper::options()->plugin('AudioPlayer')->ap_behaviour) {
+ $content = preg_replace_callback('/.*?<\/a>/si',$callback,$content);
}
- $content = preg_replace_callback("/\[(mp3)](([^]]+))\[\/\\1]/si",array('AudioPlayer_Plugin',"parseCallback"),$content);
}
return $content;
}
/**
- * 参数回调解析
+ * 摘要文本替换
*
- * @param array $matches
+ * @param string $text
* @return string
*/
- public static function parseCallback($matches)
+ public static function textparse($text,$widget,$lastResult)
{
- $atts = explode("|",$matches[3]);
- $data[0] = $atts[0];
+ $text = empty($lastResult) ? $text : $lastResult;
- for ($i=1;$iplugin('AudioPlayer');
- $archive = Typecho_Widget::widget('Widget_Archive');
-
- //文件地址
- if (function_exists("html_entity_decode")) {
- $source = html_entity_decode($source);
- }
-
- //加密地址
- if ($settings->ap_encode) {
- $playerOptions["soundFile"] = self::encodeSource($source);
- } else {
- $playerOptions["soundFile"] = $source;
+ //过滤html标签
+ $atts = explode('|',trim(Typecho_Common::stripTags($matche['2'])));
+ $files = array_shift($atts);
+
+ $pair = array();
+ $data = array();
+ foreach ($atts as $att) {
+ $pair = explode('=',$att);
+ $data[trim($pair['0'])] = trim($pair['1']);
}
- //生成实例
- $playerElementID = "audioplayer_".++self::$playerID;
- $playerCode = ''._t('播放此段音频需要Adobe Flash Player, 请点击下载最新版本并确认浏览器已开启JavaScipt支持','http://www.adobe.com/shockwave/download/download.cgi?P1_Prod_Version=ShockwaveFlash&promoid=BIOW').'
';
- $playerCode .= '';
-
- return $playerCode;
+ return self::getPlayer($files,$data,true);
}
/**
- * 输出js嵌载方法
+ * 输出播放器实例
*
+ * @param string $source 音频地址
+ * @param array $playerOptions 参数设置
+ * @param boolean $isCall 是否回调
* @return void
*/
- public static function playerjs()
+ public static function getPlayer($source,$playerOptions=array(),$isCall=false)
{
$options = Helper::options();
+ $settings = $options->plugin('AudioPlayer');
$playerurl = $options->pluginUrl.'/AudioPlayer/assets/';
- echo '';
- echo "\n";
- echo '';
- echo "\n";
+ $playerElementID = "audioplayer_".++self::$playerID;
+
+ //url编码处理
+ $source = html_entity_decode($source);
+ if (function_exists('iconv')) {
+ $address = iconv('gbk','utf-8',$source);
+ }
+ $playerOptions['soundFile'] = $settings->ap_encode ? self::encodeSource($address) : $address;
+
+ $fallback = ''._t('播放此段音频需要Adobe Flash Player, 请点击下载最新版本并确认浏览器已开启JavaScipt支持','https://get.adobe.com/flashplayer/').'';
+ //不加密可html5
+ if ($settings->ap_html5 && !$settings->ap_encode) {
+ $fallback = '';
+ $sources = explode(',',$source);
+ foreach ($sources as $source) {
+ $fallback .= '';
+ }
+ }
+
+ //播放器实例代码
+ $playerCode = '';
+ $playerCode .= '';
+ $playerCode .= ''.$fallback.'
';
+ $playerCode .= '';
+
+ //模版输出判断
+ if ($isCall) {
+ return $playerCode;
+ } else {
+ echo $playerCode;
+ }
}
/**
- * 输出配置参数
+ * 输出插件设置
*
* @return string
*/
- public static function getsets()
+ public static function getSets()
{
- //初始参数
- $options = array(
- "width"=>"290",
- "encode"=>false,
- "animation"=>true,
- "remaining"=>false,
- "checkpolicy"=>true,
- "noinfo"=>false,
- "initialvolume"=>"60",
- "buffer"=>"5",
- "rtl"=>false,
- "bg"=>"E5E5E5",
- "text"=>"333333",
- "leftbg"=>"CCCCCC",
- "lefticon"=>"333333",
- "volslider"=>"666666",
- "voltrack"=>"FFFFFF",
- "rightbg"=>"B4B4B4",
- "rightbghover"=>"999999",
- "righticon"=>"333333",
- "righticonhover"=>"FFFFFF",
- "track"=>"FFFFFF",
- "loader"=>"009900",
- "border"=>"CCCCCC",
- "tracker"=>"DDDDDD",
- "skip"=>"666666",
- "transparentpagebg"=>true
- );
-
- //设置参数
- if (isset(Helper::options()->plugins['activated']['AudioPlayer'])) {
- $settings = Helper::options()->plugin('AudioPlayer');
- $options["width"] = $settings->ap_width;
- $options["encode"] = ($settings->ap_encode)?true:false;
- $options["animation"] = ($settings->ap_animation)?false:true;
- $options["remaining"] = ($settings->ap_remaining)?true:false;
- $options["checkpolicy"] = ($settings->ap_checkpolicy)?true:false;
- $options["noinfo"] = ($settings->ap_noinfo)?true:false;
- $options["bg"] = substr($settings->ap_bgcolor,1);
- $options["text"] = substr($settings->ap_textcolor,1);
- $options["leftbg"] = substr($settings->ap_leftbgcolor,1);
- $options["lefticon"] = substr($settings->ap_lefticoncolor,1);
- $options["volslider"] = substr($settings->ap_volslidercolor,1);
- $options["voltrack"] = substr($settings->ap_voltrackcolor,1);
- $options["rightbg"] = substr($settings->ap_rightbgcolor,1);
- $options["rightbghover"] = substr($settings->ap_righticonhovercolor,1);
- $options["righticon"] = substr($settings->ap_righticoncolor,1);
- $options["righticonhover"] = substr($settings->ap_rightbghovercolor,1);
- $options["track"] = substr($settings->ap_trackcolor,1);
- $options["loader"] = substr($settings->ap_loadercolor,1);
- $options["border"] = substr($settings->ap_bordercolor,1);
- $options["tracker"] = substr($settings->ap_trackercolor,1);
- $options["skip"] = substr($settings->ap_skipcolor,1);
+ $options = Helper::options();
+ //加载默认参数
+ $ap_options = array(
+ 'width'=>'290',
+ 'initialvolume'=>'60',
+ 'buffer'=>'5',
+ 'animation'=>true,
+ 'encode'=>false,
+ 'remaining'=>false,
+ 'noinfo'=>false,
+ 'checkpolicy'=>true,
+ 'transparentpagebg'=>true,
+ 'rtl'=>false
+ );
+ $colors = self::$Colors;
+
+ //读取插件设置
+ if (isset($options->plugins['activated']['AudioPlayer'])) {
+ $settings = $options->plugin('AudioPlayer');
+ $ap_options['width'] = $settings->ap_width;
+ $ap_options['initialvolume'] = $settings->ap_initialvolume;
+ $ap_options['buffer'] = $settings->ap_buffer;
+ $ap_options['animation'] = $settings->ap_animation ? false : true;
+ $ap_options['encode'] = $settings->ap_encode ? true : false;
+ $ap_options['remaining'] = $settings->ap_remaining ? true : false;
+ $ap_options['noinfo'] = $settings->ap_noinfo ? true : false;
+
+ //解析配色数据
+ $colors = Json::decode($settings->ap_colors,true);
+ foreach ($colors as $key=>$color) {
+ $colors[$key] = substr($color,1);
+ }
}
-
- return self::php2js($options);
+ return self::php2js(array_merge($ap_options,$colors));
}
/**
- * 配置参数转js
+ * 格式化配置参数
*
* @param array $object
* @return string
*/
private static function php2js($object)
{
- $js_options = '{';
- $separator = "";
- $real_separator = ",";
+ $separator = '';
+ $real_separator = ',';
+ $js_options = '{';
foreach($object as $key=>$value) {
- //布尔型格式
- if (is_bool($value)) $value = $value?"yes":"no";
- else if (in_array($key,array("soundFile","titles","artists"))) {
- if (in_array($key,array("titles","artists"))) {
- //标题艺术家信息
- if (function_exists("html_entity_decode")) {
- $value = html_entity_decode($value);
- }
+ //布尔型处理
+ if (is_bool($value)) {
+ $value = $value ? 'yes' : 'no';
+ } elseif (in_array($key,array('soundFile','titles','artists'))) {
+ //文本型处理
+ if (in_array($key,array('titles','artists'))) {
+ $value = html_entity_decode($value);
}
$value = rawurlencode($value);
}
$js_options .= $separator.$key.':"'.$value.'"';
$separator = $real_separator;
}
-
- $js_options .= "}";
+ $js_options .= '}';
return $js_options;
}
@@ -401,17 +450,17 @@ private static function php2js($object)
*/
private static function encodeSource($string)
{
- $source = utf8_decode($string);
- $ntexto = "";
- $codekey = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789_-";
+ //对应swf解码修正
+ $string = rawurlencode($string);
+ $ntexto = '';
+ $codekey = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789_-';
for ($i=0;$itheme;
$cssfile = __TYPECHO_ROOT_DIR__.__TYPECHO_THEME_DIR__.'/'.$theme.'/style.css';
- if (file_exists($cssfile)) {
+ if (is_file($cssfile)) {
preg_match_all('/:[^:,;\{\}].*?#([abcdef1234567890]{3,6})/i',file_get_contents($cssfile),$matches);
- return array_unique($matches[1]);
+ return array_unique($matches['1']);
}
-
}
/**
@@ -444,19 +493,7 @@ private static function getThemeColors() {
*/
public static function widthformat($width)
{
- return preg_match("/^[0-9]+%?$/",$width);
- }
-
- /**
- * 判断颜色格式
- *
- * @access public
- * @param string $color
- * @return boolean
- */
- public static function colorformat($color)
- {
- return preg_match("/^#[0-9A-Fa-f]{6}$/",$color);
+ return preg_match('/^[0-9]+%?$/',$width);
}
}
diff --git a/AudioPlayer/README.md b/AudioPlayer/README.md
index 9082b412..008c1c80 100644
--- a/AudioPlayer/README.md
+++ b/AudioPlayer/README.md
@@ -1,4 +1,12 @@
-### AudioPlayer 1.2.0 for Typecho 0.9
+### Typecho音乐播放器插件AudioPlayer
+2017年1月29日更新至**v1.2.5**:
+- 修正摘要输出兼容feed提示
-详细使用说明和效果演示见blog发布地址:
-####http://www.jzwalk.com/archives/net/audio-player-for-typecho
\ No newline at end of file
+2017年1月28日更新至**v1.2.4**:
+- 重整结构优化嵌载模式效率
+- 修复短代码标签冲突等bug
+- 支持配色重置与中文url加密
+- 增加缺省可使用HTML5播放
+
+#### 详细说明与效果演示见blog发布地址:
+ > http://www.yzmb.me/archives/net/audio-player-for-typecho
\ No newline at end of file
diff --git a/AudioPlayer/assets/audio-player-admin.css b/AudioPlayer/assets/audio-player-admin.css
index d54d3b60..2d68c11a 100644
--- a/AudioPlayer/assets/audio-player-admin.css
+++ b/AudioPlayer/assets/audio-player-admin.css
@@ -1,61 +1,69 @@
#ap_colorscheme {
- position:relative;
+ position: relative;
}
+
#ap_colorselector {
- position:absolute;
- top:130px;
- left:165px;
-}
-#ap_colorselector input {
- float: left;
- margin: 0 5px 0 0;
- padding: 2px;
+ position: absolute;
+ top: 42px;
+ left: 190px;
}
#ap_colorselector input {
+ float: left;
+ margin-right: 5px;
padding: 2px;
+ width: 75px;
+ height: 23px;
+ text-transform : uppercase
}
#ap_colorsample {
float: left;
- width: 19px;
- height: 19px;
- border: 1px solid #000000;
+ width: 20px;
+ height: 20px;
+ border: 1px solid #444;
background: #FFFFFF;
}
#ap_picker-btn {
display: block;
float: left;
- height: 21px;
+ height: 23px;
background: url(picker-icon.png) no-repeat left top;
+ padding-top: 1px;
padding-left: 28px;
- padding-top: 3px;
- margin-left: 10px;
- font-size: 11px;
+ margin-left: 13px;
+ font-size: 13px;
cursor: pointer;
- color: #0000FF;
- text-decoration: underline;
+ color: #467B96;
}
#ap_themecolor-btn {
display: block;
float: left;
- height: 21px;
+ height: 23px;
background: url(theme-picker-icon.png) no-repeat left top;
- padding-left: 28px;
- padding-top: 3px;
- margin-left: 10px;
- font-size: 11px;
+ padding-top: 1px;
+ padding-left: 24px;
+ margin-left: 11px;
+ font-size: 13px;
cursor: pointer;
- color: #0000FF;
- text-decoration: underline;
+ color: #467B96;
+}
+
+#ap_resetcolor {
+ position: absolute;
+ bottom: 49px;
+ left: 132px;
+ height: 22px;
+ padding-bottom: 2px;
+ margin-bottom: 1.5px;
}
#ap_themecolor {
display: none;
width: 134px;
- padding: 0 0 13px 0;
+ padding-bottom: 13px;
float: left;
background: url(thcpck-bottom.png) no-repeat left bottom;
}
@@ -64,14 +72,14 @@
display: block;
text-indent: -9999px;
height: 13px;
- line-height: 0;
- font-size: 0;
background: url(thcpck-top.png) no-repeat left top;
}
#ap_themecolor ul {
background: url(thcpck-slice.png) repeat-y left top;
- padding: 1px 14px 1px 15px;
+ padding-top: 2px;
+ padding-right: 14px;
+ padding-left: 15px;
float: left;
width: 105px;
margin: 0;
@@ -84,7 +92,6 @@
float: left;
width: 20px;
height: 20px;
- margin: 0 1px 1px 0;
- line-height: 0;
- font-size: 0;
-}
+ margin-right: 1px;
+ margin-bottom: 1px;
+}
\ No newline at end of file
diff --git a/AudioPlayer/assets/audio-player-admin.js b/AudioPlayer/assets/audio-player-admin.js
index a3fd9c6f..3148d78d 100644
--- a/AudioPlayer/assets/audio-player-admin.js
+++ b/AudioPlayer/assets/audio-player-admin.js
@@ -1,41 +1,40 @@
(function ($) {
- var timer,
- fieldSelector,
+ var fieldSelector,
+ currentKey,
colorField,
colorPicker,
colorSwatch,
- currentColorField,
player;
-
+
var init = function () {
-
+
+ // 配色组件控制
fieldSelector = $("#ap_fieldselector");
+ currentKey = fieldSelector.val();
colorField = $("#ap_colorvalue");
colorPicker = $("#ap_picker-btn");
colorSwatch = $("#ap_colorsample");
- currentColorField = $("#ap_" + fieldSelector.val() + "color");
-
+
fieldSelector.change(function () {
- currentColorField = $("#ap_" + fieldSelector.val() + "color");
- colorField.val(currentColorField.val());
- colorPicker.ColorPickerSetColor(currentColorField.val());
- colorSwatch.css("background-color", currentColorField.val());
+ currentKey = fieldSelector.val();
+ colorField.val(colorDatas[currentKey]);
+ colorPicker.ColorPickerSetColor(colorDatas[currentKey]);
+ colorSwatch.css("background-color", colorDatas[currentKey]);
});
-
+
colorField.keyup(function () {
var color = colorField.val();
if (color.match(/#?[0-9a-f]{6}/i)) {
- currentColorField.val(color);
+ colorDatas[currentKey] = color;
colorSwatch.css("background-color", color);
- colorPicker.ColorPickerSetColor(currentColorField.val());
+ colorPicker.ColorPickerSetColor(colorDatas[currentKey]);
updatePlayer();
}
});
-
+
var themeColorPicker = $("#ap_themecolor");
if (themeColorPicker) {
themeColorPicker.css("display", "none");
- //reorderThemeColors();
themeColorPickerBtn = $("#ap_themecolor-btn");
themeColorPickerBtn.click(function (evt) {
themeColorPicker.css({
@@ -51,7 +50,7 @@
color = color.replace(/#(.)(.)(.)/, "#$1$1$2$2$3$3");
}
colorField.val(color);
- currentColorField.val(color);
+ colorDatas[currentKey] = color;
colorSwatch.css("background-color", color);
updatePlayer();
$("#ap_themecolor").css("display", "none");
@@ -61,99 +60,41 @@
themeColorPicker.hide();
});
}
-
+
colorPicker.ColorPicker({
onChange: function (hsb, hex, rgb) {
var color = "#" + hex;
colorField.val(color);
- currentColorField.val(color);
+ colorDatas[currentKey] = color;
colorSwatch.css("background-color", color);
updatePlayer();
},
-
+
onShow: function () {
themeColorPicker.hide();
}
});
-
+
selectColorField();
}
- var tabClick = function (evt) {
- var i;
- var target = $(this);
- var tab = target.parent();
-
- evt.preventDefault();
-
- if (tab.attr("class") == "current") {
- return;
- }
-
- tabs.removeClass("current");
- tab.addClass("current");
-
- panels.css("display", "none");
-
- var activeTabID = target.attr("href").replace(/[^#]*#/, "");
-
- $("#" + activeTabID).css("display", "block");
-
- if (activeTabID == "ap_panel-colour") {
- timer = setTimeout(updatePlayer, 100);
- } else if (timer) {
- clearTimeout(timer);
- }
- }
-
var selectColorField = function () {
- currentColorField = $("#ap_" + fieldSelector.val() + "color");
- colorField.val(currentColorField.val());
- colorPicker.ColorPickerSetColor(currentColorField.val());
- colorSwatch.css("background-color", currentColorField.val());
+ currentKey = fieldSelector.val();
+ colorField.val(colorDatas[currentKey]);
+ colorPicker.ColorPickerSetColor(colorDatas[currentKey]);
+ colorSwatch.css("background-color", colorDatas[currentKey]);
}
-
+
var updatePlayer = function () {
player = audioplayer_swfobject.getObjectById("ap_demoplayer");
-
- $(".typecho-option input[type=hidden]").each(function (i) {
- player.SetVariable($(this).attr("name").replace(/ap_(.+)color/, "$1"), $(this).val().replace("#", ""));
+
+ $.each(colorDatas, function(name,value){
+ player.SetVariable(name, value.replace("#", ""));
});
player.SetVariable("setcolors", 1);
+ // 更新json到隐藏域
+ colorInput.val(JSON.stringify(colorDatas));
}
-
- /*var reorderThemeColors = function () {
- var swatchList = this.themeColorPicker.getElement("ul");
- var swatches = swatchList.getElements("li");
- swatches.sort(function (a, b) {
- var colorA = new Color(a.getProperty("title"));
- var colorB = new Color(b.getProperty("title"));
- colorA = colorA.rgbToHsb();
- colorB = colorB.rgbToHsb();
- if (colorA[2] < colorB[2]) {
- return 1;
- }
- if (colorA[2] > colorB[2]) {
- return -1;
- }
- return 0;
- });
- swatches.each(function (swatch) {
- swatch.injectTop(swatchList);
- });
- }*/
-
- var pickThemeColor = function (evt) {
- var color = target.attr("title");
- if (color.length == 4) {
- color = color.replace(/#(.)(.)(.)/, "#$1$1$2$2$3$3");
- }
- $("#ap_colorvalue").val(color);
- getCurrentColorField().val(color);
- updatePlayer();
- $("#ap_picker-btn").ColorPickerSetColor(color);
- $("ap_colorsample").css("background-color", color);
- $("#ap_themecolor").css("display", "none");
- }
+
$(init);
})(jQuery);
\ No newline at end of file
diff --git a/AudioPlayer/assets/audio-player.js b/AudioPlayer/assets/audio-player.js
index 4f8b2bcd..c82921bc 100644
--- a/AudioPlayer/assets/audio-player.js
+++ b/AudioPlayer/assets/audio-player.js
@@ -1 +1,920 @@
-eval(function(p,a,c,k,e,r){e=function(c){return(c35?String.fromCharCode(c+29):c.toString(36))};if(!''.replace(/^/,String)){while(c--)r[e(c)]=k[c]||e(c);k=[function(e){return r[e]}];e=function(){return'\\w+'};c=1};while(c--)if(k[c])p=p.replace(new RegExp('\\b'+e(c)+'\\b','g'),k[c]);return p}('5 15=7(){5 w="1I",M="2a",2b="3g 2E",2F="2G.2G",1u="3h/x-3i-3j",2c="3k",2d="3l",D=1J,A=1b,W=3m,2e=F,1v=[2H],X=[],1w=[],1c=[],1l,1x,1K,2f,16=F,1y=F,R,1L,2g=H,y=7(){5 b=C A.N!=w&&C A.17!=w&&C A.P!=w,u=W.3n.Y(),p=W.3o.Y(),2I=p?/D/.T(p):/D/.T(u),1d=p?/1d/.T(p):/1d/.T(u),1M=/1M/.T(u)?3p(u.1m(/^.*1M\\/(\\d+(\\.\\d+)?).*$/,"$1")):F,G=!+"\\3q",1n=[0,0,0],d=I;3(C W.2h!=w&&C W.2h[2b]==M){d=W.2h[2b].3r;3(d&&!(C W.2i!=w&&W.2i[1u]&&!W.2i[1u].3s)){2e=H;G=F;d=d.1m(/^.*\\s+(\\S+\\s+\\S+$)/,"$1");1n[0]=L(d.1m(/^(.*)\\..*$/,"$1"),10);1n[1]=L(d.1m(/^.*\\.(.*)\\s.*$/,"$1"),10);1n[2]=/[a-2J-Z]/.T(d)?L(d.1m(/^.*[a-2J-Z]+(.*)$/,"$1"),10):0}}B 3(C D.2K!=w){1N{5 a=3t 2K(2F);3(a){d=a.2j("$2L");3(d){G=H;d=d.1e(" ")[1].1e(",");1n=[L(d[0],10),L(d[1],10),L(d[2],10)]}}}1O(e){}}z{11:b,1f:1n,U:1M,G:G,D:2I,1d:1d}}(),3u=7(){3(!y.11){z}3((C A.V!=w&&A.V=="2k")||(C A.V==w&&(A.17("1P")[0]||A.1P))){1g()}3(!16){3(C A.1o!=w){A.1o("3v",1g,F)}3(y.G&&y.D){A.1Q(2d,7(){3(A.V=="2k"){A.2M(2d,1h.1i);1g()}});3(D==3w){(7(){3(16){z}1N{A.3x.3y("3z")}1O(e){1p(1h.1i,0);z}1g()})()}}3(y.U){(7(){3(16){z}3(!/3A|2k/.T(A.V)){1p(1h.1i,0);z}1g()})()}1R(1g)}}();7 1g(){3(16){z}1N{5 t=A.17("1P")[0].1q(P("2N"));t.Q.1r(t)}1O(e){z}16=H;5 a=1v.J;E(5 i=0;i0){E(5 i=0;i0){5 e=N(b);3(e){3(1A(X[i].2Q)&&!(y.U&&y.U<1V)){18(b,H);3(c){d.1j=H;d.2m=1B(b);c(d)}}B 3(X[i].2n&&1W()){5 f={};f.1X=X[i].2n;f.13=e.14("13")||"0";f.19=e.14("19")||"0";3(e.14("1Y")){f.2o=e.14("1Y")}3(e.14("2p")){f.2p=e.14("2p")}5 g={};5 p=e.17("2q");5 h=p.J;E(5 j=0;j\'}}1G.3O=\'<2a 2x="3P:3Q-3R-3S-3T-3U"\'+d+\'>\'+e+\'2a>\';1w[1w.J]=a.O;r=N(a.O)}B{5 o=P(M);o.12("2l",1u);E(5 m K a){3(a[m]!=23.25[m]){3(m.Y()=="2o"){o.12("1Y",a[m])}B 3(m.Y()!="2x"){o.12(m,a[m])}}}E(5 n K b){3(b[n]!=23.25[n]&&n.Y()!="2r"){2Z(o,n,b[n])}}1G.Q.22(o,1G);r=o}}z r}7 2Z(a,b,c){5 p=P("2q");p.12("1C",b);p.12("2s",c);a.1q(p)}7 27(a){5 b=N(a);3(b&&b.1Z=="M"){3(y.G&&y.D){b.1k.21="1E";(7(){3(b.V==4){30(a)}B{1p(1h.1i,10)}})()}B{b.Q.1r(b)}}}7 30(a){5 b=N(a);3(b){E(5 i K b){3(C b[i]=="7"){b[i]=I}}b.Q.1r(b)}}7 N(a){5 b=I;1N{b=A.N(a)}1O(e){}z b}7 P(a){z A.P(a)}7 1s(a,b,c){a.1Q(b,c);1c[1c.J]=[a,b,c]}7 1A(a){5 b=y.1f,v=a.1e(".");v[0]=L(v[0],10);v[1]=L(v[1],10)||0;v[2]=L(v[2],10)||0;z(b[0]>v[0]||(b[0]==v[0]&&b[1]>v[1])||(b[0]==v[0]&&b[1]==v[1]&&b[2]>=v[2]))?H:F}7 1H(a,b,c,d){3(y.G&&y.1d){z}5 h=A.17("3V")[0];3(!h){z}5 m=(c&&C c=="3W")?c:"3X";3(d){R=I;1L=I}3(!R||1L!=m){5 s=P("1k");s.12("2l","3Y/3Z");s.12("40",m);R=h.1q(s);3(y.G&&y.D&&C A.28!=w&&A.28.J>0){R=A.28[A.28.J-1]}1L=m}3(y.G&&y.D){3(R&&C R.31==M){R.31(a,b)}}B{3(R&&C A.32!=w){R.1q(A.32(a+" {"+b+"}"))}}}7 18(a,b){3(!2g){z}5 v=b?"41":"2y";3(16&&N(a)){N(a).1k.2z=v}B{1H("#"+a,"2z:"+v)}}7 2A(s){5 a=/[\\\\\\"<>\\.;]/;5 b=a.42(s)!=I;z b&&C 33!=w?33(s):s}5 x=7(){3(y.G&&y.D){1J.1Q("43",7(){5 a=1c.J;E(5 i=0;i
+ is released under the MIT License
+*/
+
+var audioplayer_swfobject = function() {
+
+ var UNDEF = "undefined",
+ OBJECT = "object",
+ SHOCKWAVE_FLASH = "Shockwave Flash",
+ SHOCKWAVE_FLASH_AX = "ShockwaveFlash.ShockwaveFlash",
+ FLASH_MIME_TYPE = "application/x-shockwave-flash",
+ EXPRESS_INSTALL_ID = "SWFObjectExprInst",
+ ON_READY_STATE_CHANGE = "onreadystatechange",
+
+ win = window,
+ doc = document,
+ nav = navigator,
+
+ plugin = false,
+ domLoadFnArr = [main],
+ regObjArr = [],
+ objIdArr = [],
+ listenersArr = [],
+ storedAltContent,
+ storedAltContentId,
+ storedCallbackFn,
+ storedCallbackObj,
+ isDomLoaded = false,
+ isExpressInstallActive = false,
+ dynamicStylesheet,
+ dynamicStylesheetMedia,
+ autoHideShow = true,
+
+ /* Centralized function for browser feature detection
+ - User agent string detection is only used when no good alternative is possible
+ - Is executed directly for optimal performance
+ */
+ ua = function() {
+ var w3cdom = typeof doc.getElementById != UNDEF && typeof doc.getElementsByTagName != UNDEF && typeof doc.createElement != UNDEF,
+ u = nav.userAgent.toLowerCase(),
+ p = nav.platform.toLowerCase(),
+ windows = p ? /win/.test(p) : /win/.test(u),
+ mac = p ? /mac/.test(p) : /mac/.test(u),
+ webkit = /webkit/.test(u) ? parseFloat(u.replace(/^.*webkit\/(\d+(\.\d+)?).*$/, "$1")) : false, // returns either the webkit version or false if not webkit
+ ie = !+"\v1", // feature detection based on Andrea Giammarchi's solution: http://webreflection.blogspot.com/2009/01/32-bytes-to-know-if-your-browser-is-ie.html
+ playerVersion = [0,0,0],
+ d = null;
+ if (typeof nav.plugins != UNDEF && typeof nav.plugins[SHOCKWAVE_FLASH] == OBJECT) {
+ d = nav.plugins[SHOCKWAVE_FLASH].description;
+ if (d && !(typeof nav.mimeTypes != UNDEF && nav.mimeTypes[FLASH_MIME_TYPE] && !nav.mimeTypes[FLASH_MIME_TYPE].enabledPlugin)) { // navigator.mimeTypes["application/x-shockwave-flash"].enabledPlugin indicates whether plug-ins are enabled or disabled in Safari 3+
+ plugin = true;
+ ie = false; // cascaded feature detection for Internet Explorer
+ d = d.replace(/^.*\s+(\S+\s+\S+$)/, "$1");
+ playerVersion[0] = parseInt(d.replace(/^(.*)\..*$/, "$1"), 10);
+ playerVersion[1] = parseInt(d.replace(/^.*\.(.*)\s.*$/, "$1"), 10);
+ playerVersion[2] = /[a-zA-Z]/.test(d) ? parseInt(d.replace(/^.*[a-zA-Z]+(.*)$/, "$1"), 10) : 0;
+ }
+ }
+ else if (typeof win.ActiveXObject != UNDEF) {
+ try {
+ var a = new ActiveXObject(SHOCKWAVE_FLASH_AX);
+ if (a) { // a will return null when ActiveX is disabled
+ d = a.GetVariable("$version");
+ if (d) {
+ ie = true; // cascaded feature detection for Internet Explorer
+ d = d.split(" ")[1].split(",");
+ playerVersion = [parseInt(d[0], 10), parseInt(d[1], 10), parseInt(d[2], 10)];
+ }
+ }
+ }
+ catch(e) {}
+ }
+ return { w3:w3cdom, pv:playerVersion, wk:webkit, ie:ie, win:windows, mac:mac };
+ }(),
+
+ /* Cross-browser onDomLoad
+ - Will fire an event as soon as the DOM of a web page is loaded
+ - Internet Explorer workaround based on Diego Perini's solution: http://javascript.nwbox.com/IEContentLoaded/
+ - Regular onload serves as fallback
+ */
+ onDomLoad = function() {
+ if (!ua.w3) { return; }
+ if ((typeof doc.readyState != UNDEF && doc.readyState == "complete") || (typeof doc.readyState == UNDEF && (doc.getElementsByTagName("body")[0] || doc.body))) { // function is fired after onload, e.g. when script is inserted dynamically
+ callDomLoadFunctions();
+ }
+ if (!isDomLoaded) {
+ if (typeof doc.addEventListener != UNDEF) {
+ doc.addEventListener("DOMContentLoaded", callDomLoadFunctions, false);
+ }
+ if (ua.ie && ua.win) {
+ doc.attachEvent(ON_READY_STATE_CHANGE, function() {
+ if (doc.readyState == "complete") {
+ doc.detachEvent(ON_READY_STATE_CHANGE, arguments.callee);
+ callDomLoadFunctions();
+ }
+ });
+ if (win == top) { // if not inside an iframe
+ (function(){
+ if (isDomLoaded) { return; }
+ try {
+ doc.documentElement.doScroll("left");
+ }
+ catch(e) {
+ setTimeout(arguments.callee, 0);
+ return;
+ }
+ callDomLoadFunctions();
+ })();
+ }
+ }
+ if (ua.wk) {
+ (function(){
+ if (isDomLoaded) { return; }
+ if (!/loaded|complete/.test(doc.readyState)) {
+ setTimeout(arguments.callee, 0);
+ return;
+ }
+ callDomLoadFunctions();
+ })();
+ }
+ addLoadEvent(callDomLoadFunctions);
+ }
+ }();
+
+ function callDomLoadFunctions() {
+ if (isDomLoaded) { return; }
+ try { // test if we can really add/remove elements to/from the DOM; we don't want to fire it too early
+ var t = doc.getElementsByTagName("body")[0].appendChild(createElement("span"));
+ t.parentNode.removeChild(t);
+ }
+ catch (e) { return; }
+ isDomLoaded = true;
+ var dl = domLoadFnArr.length;
+ for (var i = 0; i < dl; i++) {
+ domLoadFnArr[i]();
+ }
+ }
+
+ function addDomLoadEvent(fn) {
+ if (isDomLoaded) {
+ fn();
+ }
+ else {
+ domLoadFnArr[domLoadFnArr.length] = fn; // Array.push() is only available in IE5.5+
+ }
+ }
+
+ /* Cross-browser onload
+ - Based on James Edwards' solution: http://brothercake.com/site/resources/scripts/onload/
+ - Will fire an event as soon as a web page including all of its assets are loaded
+ */
+ function addLoadEvent(fn) {
+ if (typeof win.addEventListener != UNDEF) {
+ win.addEventListener("load", fn, false);
+ }
+ else if (typeof doc.addEventListener != UNDEF) {
+ doc.addEventListener("load", fn, false);
+ }
+ else if (typeof win.attachEvent != UNDEF) {
+ addListener(win, "onload", fn);
+ }
+ else if (typeof win.onload == "function") {
+ var fnOld = win.onload;
+ win.onload = function() {
+ fnOld();
+ fn();
+ };
+ }
+ else {
+ win.onload = fn;
+ }
+ }
+
+ /* Main function
+ - Will preferably execute onDomLoad, otherwise onload (as a fallback)
+ */
+ function main() {
+ if (plugin) {
+ testPlayerVersion();
+ }
+ else {
+ matchVersions();
+ }
+ }
+
+ /* Detect the Flash Player version for non-Internet Explorer browsers
+ - Detecting the plug-in version via the object element is more precise than using the plugins collection item's description:
+ a. Both release and build numbers can be detected
+ b. Avoid wrong descriptions by corrupt installers provided by Adobe
+ c. Avoid wrong descriptions by multiple Flash Player entries in the plugin Array, caused by incorrect browser imports
+ - Disadvantage of this method is that it depends on the availability of the DOM, while the plugins collection is immediately available
+ */
+ function testPlayerVersion() {
+ var b = doc.getElementsByTagName("body")[0];
+ var o = createElement(OBJECT);
+ o.setAttribute("type", FLASH_MIME_TYPE);
+ var t = b.appendChild(o);
+ if (t) {
+ var counter = 0;
+ (function(){
+ if (typeof t.GetVariable != UNDEF) {
+ var d = t.GetVariable("$version");
+ if (d) {
+ d = d.split(" ")[1].split(",");
+ ua.pv = [parseInt(d[0], 10), parseInt(d[1], 10), parseInt(d[2], 10)];
+ }
+ }
+ else if (counter < 10) {
+ counter++;
+ setTimeout(arguments.callee, 10);
+ return;
+ }
+ b.removeChild(o);
+ t = null;
+ matchVersions();
+ })();
+ }
+ else {
+ matchVersions();
+ }
+ }
+
+ /* Perform Flash Player and SWF version matching; static publishing only
+ */
+ function matchVersions() {
+ var rl = regObjArr.length;
+ if (rl > 0) {
+ for (var i = 0; i < rl; i++) { // for each registered object element
+ var id = regObjArr[i].id;
+ var cb = regObjArr[i].callbackFn;
+ var cbObj = {success:false, id:id};
+ if (ua.pv[0] > 0) {
+ var obj = getElementById(id);
+ if (obj) {
+ if (hasPlayerVersion(regObjArr[i].swfVersion) && !(ua.wk && ua.wk < 312)) { // Flash Player version >= published SWF version: Houston, we have a match!
+ setVisibility(id, true);
+ if (cb) {
+ cbObj.success = true;
+ cbObj.ref = getObjectById(id);
+ cb(cbObj);
+ }
+ }
+ else if (regObjArr[i].expressInstall && canExpressInstall()) { // show the Adobe Express Install dialog if set by the web page author and if supported
+ var att = {};
+ att.data = regObjArr[i].expressInstall;
+ att.width = obj.getAttribute("width") || "0";
+ att.height = obj.getAttribute("height") || "0";
+ if (obj.getAttribute("class")) { att.styleclass = obj.getAttribute("class"); }
+ if (obj.getAttribute("align")) { att.align = obj.getAttribute("align"); }
+ // parse HTML object param element's name-value pairs
+ var par = {};
+ var p = obj.getElementsByTagName("param");
+ var pl = p.length;
+ for (var j = 0; j < pl; j++) {
+ if (p[j].getAttribute("name").toLowerCase() != "movie") {
+ par[p[j].getAttribute("name")] = p[j].getAttribute("value");
+ }
+ }
+ showExpressInstall(att, par, id, cb);
+ }
+ else { // Flash Player and SWF version mismatch or an older Webkit engine that ignores the HTML object element's nested param elements: display alternative content instead of SWF
+ displayAltContent(obj);
+ if (cb) { cb(cbObj); }
+ }
+ }
+ }
+ else { // if no Flash Player is installed or the fp version cannot be detected we let the HTML object element do its job (either show a SWF or alternative content)
+ setVisibility(id, true);
+ if (cb) {
+ var o = getObjectById(id); // test whether there is an HTML object element or not
+ if (o && typeof o.SetVariable != UNDEF) {
+ cbObj.success = true;
+ cbObj.ref = o;
+ }
+ cb(cbObj);
+ }
+ }
+ }
+ }
+ }
+
+ function getObjectById(objectIdStr) {
+ var r = null;
+ var o = getElementById(objectIdStr);
+ if (o && o.nodeName == "OBJECT") {
+ if (typeof o.SetVariable != UNDEF) {
+ r = o;
+ }
+ else {
+ var n = o.getElementsByTagName(OBJECT)[0];
+ if (n) {
+ r = n;
+ }
+ }
+ }
+ return r;
+ }
+
+ /* Requirements for Adobe Express Install
+ - only one instance can be active at a time
+ - fp 6.0.65 or higher
+ - Win/Mac OS only
+ - no Webkit engines older than version 312
+ */
+ function canExpressInstall() {
+ return !isExpressInstallActive && hasPlayerVersion("6.0.65") && (ua.win || ua.mac) && !(ua.wk && ua.wk < 312);
+ }
+
+ /* Show the Adobe Express Install dialog
+ - Reference: http://www.adobe.com/cfusion/knowledgebase/index.cfm?id=6a253b75
+ */
+ function showExpressInstall(att, par, replaceElemIdStr, callbackFn) {
+ isExpressInstallActive = true;
+ storedCallbackFn = callbackFn || null;
+ storedCallbackObj = {success:false, id:replaceElemIdStr};
+ var obj = getElementById(replaceElemIdStr);
+ if (obj) {
+ if (obj.nodeName == "OBJECT") { // static publishing
+ storedAltContent = abstractAltContent(obj);
+ storedAltContentId = null;
+ }
+ else { // dynamic publishing
+ storedAltContent = obj;
+ storedAltContentId = replaceElemIdStr;
+ }
+ att.id = EXPRESS_INSTALL_ID;
+ if (typeof att.width == UNDEF || (!/%$/.test(att.width) && parseInt(att.width, 10) < 310)) { att.width = "310"; }
+ if (typeof att.height == UNDEF || (!/%$/.test(att.height) && parseInt(att.height, 10) < 137)) { att.height = "137"; }
+ doc.title = doc.title.slice(0, 47) + " - Flash Player Installation";
+ var pt = ua.ie && ua.win ? "ActiveX" : "PlugIn",
+ fv = "MMredirectURL=" + win.location.toString().replace(/&/g,"%26") + "&MMplayerType=" + pt + "&MMdoctitle=" + doc.title;
+ if (typeof par.flashvars != UNDEF) {
+ par.flashvars += "&" + fv;
+ }
+ else {
+ par.flashvars = fv;
+ }
+ // IE only: when a SWF is loading (AND: not available in cache) wait for the readyState of the object element to become 4 before removing it,
+ // because you cannot properly cancel a loading SWF file without breaking browser load references, also obj.onreadystatechange doesn't work
+ if (ua.ie && ua.win && obj.readyState != 4) {
+ var newObj = createElement("div");
+ replaceElemIdStr += "SWFObjectNew";
+ newObj.setAttribute("id", replaceElemIdStr);
+ obj.parentNode.insertBefore(newObj, obj); // insert placeholder div that will be replaced by the object element that loads expressinstall.swf
+ obj.style.display = "none";
+ (function(){
+ if (obj.readyState == 4) {
+ obj.parentNode.removeChild(obj);
+ }
+ else {
+ setTimeout(arguments.callee, 10);
+ }
+ })();
+ }
+ createSWF(att, par, replaceElemIdStr);
+ }
+ }
+
+ /* Functions to abstract and display alternative content
+ */
+ function displayAltContent(obj) {
+ if (ua.ie && ua.win && obj.readyState != 4) {
+ // IE only: when a SWF is loading (AND: not available in cache) wait for the readyState of the object element to become 4 before removing it,
+ // because you cannot properly cancel a loading SWF file without breaking browser load references, also obj.onreadystatechange doesn't work
+ var el = createElement("div");
+ obj.parentNode.insertBefore(el, obj); // insert placeholder div that will be replaced by the alternative content
+ el.parentNode.replaceChild(abstractAltContent(obj), el);
+ obj.style.display = "none";
+ (function(){
+ if (obj.readyState == 4) {
+ obj.parentNode.removeChild(obj);
+ }
+ else {
+ setTimeout(arguments.callee, 10);
+ }
+ })();
+ }
+ else {
+ obj.parentNode.replaceChild(abstractAltContent(obj), obj);
+ }
+ }
+
+ function abstractAltContent(obj) {
+ var ac = createElement("div");
+ if (ua.win && ua.ie) {
+ ac.innerHTML = obj.innerHTML;
+ }
+ else {
+ var nestedObj = obj.getElementsByTagName(OBJECT)[0];
+ if (nestedObj) {
+ var c = nestedObj.childNodes;
+ if (c) {
+ var cl = c.length;
+ for (var i = 0; i < cl; i++) {
+ if (!(c[i].nodeType == 1 && c[i].nodeName == "PARAM") && !(c[i].nodeType == 8)) {
+ ac.appendChild(c[i].cloneNode(true));
+ }
+ }
+ }
+ }
+ }
+ return ac;
+ }
+
+ /* Cross-browser dynamic SWF creation
+ */
+ function createSWF(attObj, parObj, id) {
+ var r, el = getElementById(id);
+ if (ua.wk && ua.wk < 312) { return r; }
+ if (el) {
+ if (typeof attObj.id == UNDEF) { // if no 'id' is defined for the object element, it will inherit the 'id' from the alternative content
+ attObj.id = id;
+ }
+ if (ua.ie && ua.win) { // Internet Explorer + the HTML object element + W3C DOM methods do not combine: fall back to outerHTML
+ var att = "";
+ for (var i in attObj) {
+ if (attObj[i] != Object.prototype[i]) { // filter out prototype additions from other potential libraries
+ if (i.toLowerCase() == "data") {
+ parObj.movie = attObj[i];
+ }
+ else if (i.toLowerCase() == "styleclass") { // 'class' is an ECMA4 reserved keyword
+ att += ' class="' + attObj[i] + '"';
+ }
+ else if (i.toLowerCase() != "classid") {
+ att += ' ' + i + '="' + attObj[i] + '"';
+ }
+ }
+ }
+ var par = "";
+ for (var j in parObj) {
+ if (parObj[j] != Object.prototype[j]) { // filter out prototype additions from other potential libraries
+ par += '';
+ }
+ }
+ el.outerHTML = '';
+ objIdArr[objIdArr.length] = attObj.id; // stored to fix object 'leaks' on unload (dynamic publishing only)
+ r = getElementById(attObj.id);
+ }
+ else { // well-behaving browsers
+ var o = createElement(OBJECT);
+ o.setAttribute("type", FLASH_MIME_TYPE);
+ for (var m in attObj) {
+ if (attObj[m] != Object.prototype[m]) { // filter out prototype additions from other potential libraries
+ if (m.toLowerCase() == "styleclass") { // 'class' is an ECMA4 reserved keyword
+ o.setAttribute("class", attObj[m]);
+ }
+ else if (m.toLowerCase() != "classid") { // filter out IE specific attribute
+ o.setAttribute(m, attObj[m]);
+ }
+ }
+ }
+ for (var n in parObj) {
+ if (parObj[n] != Object.prototype[n] && n.toLowerCase() != "movie") { // filter out prototype additions from other potential libraries and IE specific param element
+ createObjParam(o, n, parObj[n]);
+ }
+ }
+ el.parentNode.replaceChild(o, el);
+ r = o;
+ }
+ }
+ return r;
+ }
+
+ function createObjParam(el, pName, pValue) {
+ var p = createElement("param");
+ p.setAttribute("name", pName);
+ p.setAttribute("value", pValue);
+ el.appendChild(p);
+ }
+
+ /* Cross-browser SWF removal
+ - Especially needed to safely and completely remove a SWF in Internet Explorer
+ */
+ function removeSWF(id) {
+ var obj = getElementById(id);
+ if (obj && obj.nodeName == "OBJECT") {
+ if (ua.ie && ua.win) {
+ obj.style.display = "none";
+ (function(){
+ if (obj.readyState == 4) {
+ removeObjectInIE(id);
+ }
+ else {
+ setTimeout(arguments.callee, 10);
+ }
+ })();
+ }
+ else {
+ obj.parentNode.removeChild(obj);
+ }
+ }
+ }
+
+ function removeObjectInIE(id) {
+ var obj = getElementById(id);
+ if (obj) {
+ for (var i in obj) {
+ if (typeof obj[i] == "function") {
+ obj[i] = null;
+ }
+ }
+ obj.parentNode.removeChild(obj);
+ }
+ }
+
+ /* Functions to optimize JavaScript compression
+ */
+ function getElementById(id) {
+ var el = null;
+ try {
+ el = doc.getElementById(id);
+ }
+ catch (e) {}
+ return el;
+ }
+
+ function createElement(el) {
+ return doc.createElement(el);
+ }
+
+ /* Updated attachEvent function for Internet Explorer
+ - Stores attachEvent information in an Array, so on unload the detachEvent functions can be called to avoid memory leaks
+ */
+ function addListener(target, eventType, fn) {
+ target.attachEvent(eventType, fn);
+ listenersArr[listenersArr.length] = [target, eventType, fn];
+ }
+
+ /* Flash Player and SWF content version matching
+ */
+ function hasPlayerVersion(rv) {
+ var pv = ua.pv, v = rv.split(".");
+ v[0] = parseInt(v[0], 10);
+ v[1] = parseInt(v[1], 10) || 0; // supports short notation, e.g. "9" instead of "9.0.0"
+ v[2] = parseInt(v[2], 10) || 0;
+ return (pv[0] > v[0] || (pv[0] == v[0] && pv[1] > v[1]) || (pv[0] == v[0] && pv[1] == v[1] && pv[2] >= v[2])) ? true : false;
+ }
+
+ /* Cross-browser dynamic CSS creation
+ - Based on Bobby van der Sluis' solution: http://www.bobbyvandersluis.com/articles/dynamicCSS.php
+ */
+ function createCSS(sel, decl, media, newStyle) {
+ if (ua.ie && ua.mac) { return; }
+ var h = doc.getElementsByTagName("head")[0];
+ if (!h) { return; } // to also support badly authored HTML pages that lack a head element
+ var m = (media && typeof media == "string") ? media : "screen";
+ if (newStyle) {
+ dynamicStylesheet = null;
+ dynamicStylesheetMedia = null;
+ }
+ if (!dynamicStylesheet || dynamicStylesheetMedia != m) {
+ // create dynamic stylesheet + get a global reference to it
+ var s = createElement("style");
+ s.setAttribute("type", "text/css");
+ s.setAttribute("media", m);
+ dynamicStylesheet = h.appendChild(s);
+ if (ua.ie && ua.win && typeof doc.styleSheets != UNDEF && doc.styleSheets.length > 0) {
+ dynamicStylesheet = doc.styleSheets[doc.styleSheets.length - 1];
+ }
+ dynamicStylesheetMedia = m;
+ }
+ // add style rule
+ if (ua.ie && ua.win) {
+ if (dynamicStylesheet && typeof dynamicStylesheet.addRule == OBJECT) {
+ dynamicStylesheet.addRule(sel, decl);
+ }
+ }
+ else {
+ if (dynamicStylesheet && typeof doc.createTextNode != UNDEF) {
+ dynamicStylesheet.appendChild(doc.createTextNode(sel + " {" + decl + "}"));
+ }
+ }
+ }
+
+ function setVisibility(id, isVisible) {
+ if (!autoHideShow) { return; }
+ var v = isVisible ? "visible" : "hidden";
+ if (isDomLoaded && getElementById(id)) {
+ getElementById(id).style.visibility = v;
+ }
+ else {
+ createCSS("#" + id, "visibility:" + v);
+ }
+ }
+
+ /* Filter to avoid XSS attacks
+ */
+ function urlEncodeIfNecessary(s) {
+ var regex = /[\\\"<>\.;]/;
+ var hasBadChars = regex.exec(s) != null;
+ return hasBadChars && typeof encodeURIComponent != UNDEF ? encodeURIComponent(s) : s;
+ }
+
+ /* Release memory to avoid memory leaks caused by closures, fix hanging audio/video threads and force open sockets/NetConnections to disconnect (Internet Explorer only)
+ */
+ var cleanup = function() {
+ if (ua.ie && ua.win) {
+ window.attachEvent("onunload", function() {
+ // remove listeners to avoid memory leaks
+ var ll = listenersArr.length;
+ for (var i = 0; i < ll; i++) {
+ listenersArr[i][0].detachEvent(listenersArr[i][1], listenersArr[i][2]);
+ }
+ // cleanup dynamically embedded objects to fix audio/video threads and force open sockets and NetConnections to disconnect
+ var il = objIdArr.length;
+ for (var j = 0; j < il; j++) {
+ removeSWF(objIdArr[j]);
+ }
+ // cleanup library's main closures to avoid memory leaks
+ for (var k in ua) {
+ ua[k] = null;
+ }
+ ua = null;
+ for (var l in audioplayer_swfobject) {
+ audioplayer_swfobject[l] = null;
+ }
+ audioplayer_swfobject = null;
+ });
+ }
+ }();
+
+ return {
+ /* Public API
+ - Reference: http://code.google.com/p/swfobject/wiki/documentation
+ */
+ registerObject: function(objectIdStr, swfVersionStr, xiSwfUrlStr, callbackFn) {
+ if (ua.w3 && objectIdStr && swfVersionStr) {
+ var regObj = {};
+ regObj.id = objectIdStr;
+ regObj.swfVersion = swfVersionStr;
+ regObj.expressInstall = xiSwfUrlStr;
+ regObj.callbackFn = callbackFn;
+ regObjArr[regObjArr.length] = regObj;
+ setVisibility(objectIdStr, false);
+ }
+ else if (callbackFn) {
+ callbackFn({success:false, id:objectIdStr});
+ }
+ },
+
+ getObjectById: function(objectIdStr) {
+ if (ua.w3) {
+ return getObjectById(objectIdStr);
+ }
+ },
+
+ embedSWF: function(swfUrlStr, replaceElemIdStr, widthStr, heightStr, swfVersionStr, xiSwfUrlStr, flashvarsObj, parObj, attObj, callbackFn) {
+ var callbackObj = {success:false, id:replaceElemIdStr};
+ if (ua.w3 && !(ua.wk && ua.wk < 312) && swfUrlStr && replaceElemIdStr && widthStr && heightStr && swfVersionStr) {
+ setVisibility(replaceElemIdStr, false);
+ addDomLoadEvent(function() {
+ widthStr += ""; // auto-convert to string
+ heightStr += "";
+ var att = {};
+ if (attObj && typeof attObj === OBJECT) {
+ for (var i in attObj) { // copy object to avoid the use of references, because web authors often reuse attObj for multiple SWFs
+ att[i] = attObj[i];
+ }
+ }
+ att.data = swfUrlStr;
+ att.width = widthStr;
+ att.height = heightStr;
+ var par = {};
+ if (parObj && typeof parObj === OBJECT) {
+ for (var j in parObj) { // copy object to avoid the use of references, because web authors often reuse parObj for multiple SWFs
+ par[j] = parObj[j];
+ }
+ }
+ if (flashvarsObj && typeof flashvarsObj === OBJECT) {
+ for (var k in flashvarsObj) { // copy object to avoid the use of references, because web authors often reuse flashvarsObj for multiple SWFs
+ if (typeof par.flashvars != UNDEF) {
+ par.flashvars += "&" + k + "=" + flashvarsObj[k];
+ }
+ else {
+ par.flashvars = k + "=" + flashvarsObj[k];
+ }
+ }
+ }
+ if (hasPlayerVersion(swfVersionStr)) { // create SWF
+ var obj = createSWF(att, par, replaceElemIdStr);
+ if (att.id == replaceElemIdStr) {
+ setVisibility(replaceElemIdStr, true);
+ }
+ callbackObj.success = true;
+ callbackObj.ref = obj;
+ }
+ else if (xiSwfUrlStr && canExpressInstall()) { // show Adobe Express Install
+ att.data = xiSwfUrlStr;
+ showExpressInstall(att, par, replaceElemIdStr, callbackFn);
+ return;
+ }
+ else { // show alternative content
+ setVisibility(replaceElemIdStr, true);
+ }
+ if (callbackFn) { callbackFn(callbackObj); }
+ });
+ }
+ else if (callbackFn) { callbackFn(callbackObj); }
+ },
+
+ switchOffAutoHideShow: function() {
+ autoHideShow = false;
+ },
+
+ ua: ua,
+
+ getFlashPlayerVersion: function() {
+ return { major:ua.pv[0], minor:ua.pv[1], release:ua.pv[2] };
+ },
+
+ hasFlashPlayerVersion: hasPlayerVersion,
+
+ createSWF: function(attObj, parObj, replaceElemIdStr) {
+ if (ua.w3) {
+ return createSWF(attObj, parObj, replaceElemIdStr);
+ }
+ else {
+ return undefined;
+ }
+ },
+
+ showExpressInstall: function(att, par, replaceElemIdStr, callbackFn) {
+ if (ua.w3 && canExpressInstall()) {
+ showExpressInstall(att, par, replaceElemIdStr, callbackFn);
+ }
+ },
+
+ removeSWF: function(objElemIdStr) {
+ if (ua.w3) {
+ removeSWF(objElemIdStr);
+ }
+ },
+
+ createCSS: function(selStr, declStr, mediaStr, newStyleBoolean) {
+ if (ua.w3) {
+ createCSS(selStr, declStr, mediaStr, newStyleBoolean);
+ }
+ },
+
+ addDomLoadEvent: addDomLoadEvent,
+
+ addLoadEvent: addLoadEvent,
+
+ getQueryParamValue: function(param) {
+ var q = doc.location.search || doc.location.hash;
+ if (q) {
+ if (/\?/.test(q)) { q = q.split("?")[1]; } // strip question mark
+ if (param == null) {
+ return urlEncodeIfNecessary(q);
+ }
+ var pairs = q.split("&");
+ for (var i = 0; i < pairs.length; i++) {
+ if (pairs[i].substring(0, pairs[i].indexOf("=")) == param) {
+ return urlEncodeIfNecessary(pairs[i].substring((pairs[i].indexOf("=") + 1)));
+ }
+ }
+ }
+ return "";
+ },
+
+ // For internal usage only
+ expressInstallCallback: function() {
+ if (isExpressInstallActive) {
+ var obj = getElementById(EXPRESS_INSTALL_ID);
+ if (obj && storedAltContent) {
+ obj.parentNode.replaceChild(storedAltContent, obj);
+ if (storedAltContentId) {
+ setVisibility(storedAltContentId, true);
+ if (ua.ie && ua.win) { storedAltContent.style.display = "block"; }
+ }
+ if (storedCallbackFn) { storedCallbackFn(storedCallbackObj); }
+ }
+ isExpressInstallActive = false;
+ }
+ }
+ };
+}();
+var AudioPlayer = function () {
+ var instances = [];
+ var groups = {};
+ var activePlayers = {};
+ var playerURL = "";
+ var defaultOptions = {};
+ var currentVolume = -1;
+ var requiredFlashVersion = "9";
+
+ function getPlayer(playerID) {
+ if (document.all && !window[playerID]) {
+ for (var i = 0; i < document.forms.length; i++) {
+ if (document.forms[i][playerID]) {
+ return document.forms[i][playerID];
+ break;
+ }
+ }
+ }
+ return document.all ? window[playerID] : document[playerID];
+ }
+
+ function addListener (playerID, type, func) {
+ getPlayer(playerID).addListener(type, func);
+ }
+
+ return {
+ setup: function (url, options) {
+ playerURL = url;
+ defaultOptions = options;
+ if (audioplayer_swfobject.hasFlashPlayerVersion(requiredFlashVersion)) {
+ audioplayer_swfobject.switchOffAutoHideShow();
+ audioplayer_swfobject.createCSS("p.audioplayer_container span", "visibility:hidden;height:24px;overflow:hidden;padding:0;border:none;");
+ }
+ },
+
+ getPlayer: function (playerID) {
+ return getPlayer(playerID);
+ },
+
+ addListener: function (playerID, type, func) {
+ addListener(playerID, type, func);
+ },
+
+ embed: function (elementID, options) {
+ var instanceOptions = {};
+ var key;
+
+ var flashParams = {};
+ var flashVars = {};
+ var flashAttributes = {};
+
+ // Merge default options and instance options
+ for (key in defaultOptions) {
+ instanceOptions[key] = defaultOptions[key];
+ }
+ for (key in options) {
+ instanceOptions[key] = options[key];
+ }
+
+ if (instanceOptions.transparentpagebg == "yes") {
+ flashParams.bgcolor = "#FFFFFF";
+ flashParams.wmode = "transparent";
+ } else {
+ if (instanceOptions.pagebg) {
+ flashParams.bgcolor = "#" + instanceOptions.pagebg;
+ }
+ flashParams.wmode = "opaque";
+ }
+
+ flashParams.menu = "false";
+
+ for (key in instanceOptions) {
+ if (key == "pagebg" || key == "width" || key == "transparentpagebg") {
+ continue;
+ }
+ flashVars[key] = instanceOptions[key];
+ }
+
+ flashAttributes.name = elementID;
+ flashAttributes.style = "outline: none";
+
+ flashVars.playerID = elementID;
+
+ audioplayer_swfobject.embedSWF(playerURL, elementID, instanceOptions.width.toString(), "24", requiredFlashVersion, false, flashVars, flashParams, flashAttributes);
+
+ instances.push(elementID);
+
+ if (options.group) {
+ groups[elementID] = options.group;
+ }
+ },
+
+ syncVolumes: function (playerID, volume) {
+ if (groups[playerID]) return;
+ currentVolume = volume;
+ for (var i = 0; i < instances.length; i++) {
+ if (!groups[instances[i]] && instances[i] != playerID) {
+ getPlayer(instances[i]).setVolume(currentVolume);
+ }
+ }
+ },
+
+ activate: function (playerID, info) {
+ for (var activePlayerID in activePlayers) {
+ if (activePlayerID == playerID) {
+ continue;
+ }
+ if (groups[playerID] != groups[activePlayerID]) {
+ this.close(activePlayerID);
+ continue;
+ }
+ if (!(groups[playerID] || groups[activePlayerID])) {
+ this.close(activePlayerID);
+ }
+ }
+ activePlayers[playerID] = 1;
+ },
+
+ load: function (playerID, soundFile, titles, artists) {
+ getPlayer(playerID).load(soundFile, titles, artists);
+ },
+
+ close: function (playerID) {
+ getPlayer(playerID).close();
+ if (playerID in activePlayers) {
+ delete activePlayers[playerID];
+ }
+ },
+
+ open: function (playerID, index) {
+ if (index == undefined) {
+ index = 1;
+ }
+ getPlayer(playerID).open(index == undefined ? 0 : index-1);
+ },
+
+ getVolume: function (playerID) {
+ return currentVolume;
+ }
+
+ }
+
+}();
diff --git a/AudioPlayer/assets/player.swf b/AudioPlayer/assets/player.swf
index bf05ee55..31275821 100644
Binary files a/AudioPlayer/assets/player.swf and b/AudioPlayer/assets/player.swf differ