Commit 12d70dec authored by niminmin's avatar niminmin

[feat]图片预览及附件一键下载

parent afe6a3f9
...@@ -32,3 +32,4 @@ atm_upload_unUseSubFolder.svc ...@@ -32,3 +32,4 @@ atm_upload_unUseSubFolder.svc
!/src/main/webapp/WEB-INF/uncertain.local.xml !/src/main/webapp/WEB-INF/uncertain.local.xml
src/main/webapp/WEB-INF/uncertain.local.xml src/main/webapp/WEB-INF/uncertain.local.xml
src/main/webapp/WEB-INF/uncertain.local.xml src/main/webapp/WEB-INF/uncertain.local.xml
src/main/java/leaf/presentation/component/std/Grid.java
package leaf.presentation.component.std;
import com.hand.hls.office.utils.ConfigUtils;
import leaf.application.ApplicationViewConfig;
import leaf.application.LeafApplication;
import leaf.presentation.BuildSession;
import leaf.presentation.ViewContext;
import leaf.presentation.component.std.config.*;
import org.json.JSONArray;
import org.json.JSONObject;
import uncertain.composite.CompositeMap;
import uncertain.composite.CompositeUtil;
import uncertain.composite.TextParser;
import uncertain.ocm.IObjectRegistry;
import java.io.IOException;
import java.util.*;
/**
*
* @version $Id: Grid.java,v 1.1 2016/09/02 08:21:30 wuhuazhen2689 Exp $
* @author <a href="mailto:znjqolf@126.com">vincent</a>
*/
@SuppressWarnings("unchecked")
public class Grid extends Component {
public static final String VERSION = "$Revision: 1.1 $";
public static final String HTML_LOCKAREA = "lockarea";
public static final String HTML_UNLOCKAREA = "unlockarea";
private static final String DEFAULT_CLASS = "item-grid-wrap";
private static final String MAX_ROWS = "maxRow";
private static final String ROW_SPAN = "rowspan";
private static final String COL_SPAN = "colspan";
private static final String ROW_HEIGHT = "rowHeight";
private static final String HEAD_HEIGHT = "headHeight";
private static final String LOCK_WIDTH = "lockwidth";
private static final String UNLOCK_WIDTH = "unlockwidth";
private static final String BODY_HEIGHT = "bodyHeight";
private static final String ROW_WIDTH = "rowWidth";
private static final String TABLE_HEIGHT = "tableHeight";
private static final String FOOTER_BAR = "footerBar";
private static final String LOCK_COLUMNS = "lockcolumns";
private static final String UNLOCK_COLUMNS = "unlockcolumns";
private static final String UNLOCK_FILTER = "unlockfilter";
private static final String COLUMN_TYPE = "type";
private static final String TYPE_CELL_CHECKBOX = "cellcheck";
// private static final String TYPE_CELL_RADIO = "cellradio";
private static final String TYPE_ROW_CHECKBOX = "rowcheck";
private static final String TYPE_ROW_RADIO = "rowradio";
private static final String TYPE_ROW_NUMBER = "rownumber";
private static final String COMPONENT_BUTTON = "button";
private static final String TYPE_EXCEL = "excel";
private static final String LEAF_EXCEL_BUTTON = "leaf.gridExcelButton";
private int rowHeight = 25;
private int headHeight = 25;
private int navbarHeight = 25;
private boolean hasFooterBar = false;
public Grid(IObjectRegistry registry) {
super(registry);
}
public void onPreparePageContent(BuildSession session, ViewContext context) throws IOException {
super.onPreparePageContent(session, context);
addStyleSheet(session, context, "grid/Grid-min.css");
addJavaScript(session, context, "grid/Grid-min.js");
}
protected int getDefaultWidth(BuildSession session) {
return 800;
}
protected String getDefaultClass(BuildSession session, ViewContext context){
CompositeMap view = context.getView();
CompositeMap model = context.getModel();
GridConfig gcc = GridConfig.getInstance(view);
String cls = DEFAULT_CLASS;
if(gcc.isAutoShowFilter()){
cls += " grid-filtering";
}
if(!gcc.hasEditorBorder(model,mDefaultEditorBorder)||THEME_BESTSELLER.equals(session.getTheme())||THEME_HLS_DEFAULT.equals(session.getTheme())){
addConfig(GridConfig.PROPERTITY_EDITOR_BORDER, Boolean.FALSE);
return cls + " none-editor-border";
}
return cls;
}
private int mDefaultMarginSize = ApplicationViewConfig.DEFAULT_MARGIN_WIDTH;
private boolean mDefaultAutoAppend = ApplicationViewConfig.DEFAULT_AUTO_APPEND;
private boolean mDefaultGridSubmask = ApplicationViewConfig.DEFAULT_GRID_SUBMASK;
private boolean mDefaultEditorBorder = ApplicationViewConfig.DEFAULT_EDITOR_BORDER;
private boolean mDefaultAutoCount = ApplicationViewConfig.DEFAULT_AUTO_COUNT;
private boolean mDefaultAutoAdjustGrid = ApplicationViewConfig.DEFAULT_AUTO_ADJUST_GRID;
private boolean mDefaultAutoAdjustGridColumn = ApplicationViewConfig.DEFAULT_AUTO_ADJUST_GRID_COLUMN;
private boolean mDefaultInfiniteLoad = ApplicationViewConfig.DEFAULT_INFINITE_LOAD;
private boolean isBestseller = false;
private boolean isHlsDefault = false;
private boolean isHap = false;
private boolean hasFilter = false;
private boolean isAutoShowFilter = true;
public void onCreateViewContent(BuildSession session, ViewContext context) throws IOException{
CompositeMap view = context.getView();
if(null!=mApplicationConfig){
ApplicationViewConfig view_config = mApplicationConfig.getApplicationViewConfig();
if (null != view_config) {
mDefaultMarginSize = view_config.getDefaultMarginWidth();
mDefaultAutoAppend = view_config.getDefaultAutoAppend();
mDefaultGridSubmask = view_config.getDefaultGridSubmask();
mDefaultEditorBorder = view_config.getDefaultEditorBorder();
mDefaultAutoCount = view_config.getDefaultAutoCount();
mDefaultAutoAdjustGrid = view_config.getDefaultAutoAdjustGrid();
mDefaultAutoAdjustGridColumn = view_config.getDefaultAutoAdjustGridColumn();
mDefaultInfiniteLoad = view_config.getDefaultInfiniteLoad();
}
}
if(mDefaultMarginSize != -1){
view.putInt(ComponentConfig.PROPERTITY_MARGIN_WIDTH, mDefaultMarginSize);
}
CompositeMap model = context.getModel();
super.onCreateViewContent(session, context);
GridConfig gc = GridConfig.getInstance(view);
Map map = context.getMap();
String theme = session.getTheme();
isBestseller = THEME_BESTSELLER.equals(theme);
isHlsDefault = THEME_HLS_DEFAULT.equals(theme);
isHap = theme.indexOf(THEME_HAP)==-1?false:true;
if(isHap){
rowHeight=35;
headHeight=32;
navbarHeight=39;
}else {
rowHeight = gc.getRowHeight(isBestseller ? 40 : isHlsDefault ? 33 : 25);
headHeight = isBestseller ? 50 : isHlsDefault ? 38 : 25;
navbarHeight = isBestseller ? 50 : isHlsDefault ? 36 : 25;
}
boolean hasToolBar = creatToolBar(session,context);
hasFooterBar = hasFooterBar(gc.getColumns(),model);
boolean hasNavBar = createNavgationToolBar(session,context);
isAutoShowFilter = gc.isAutoShowFilter();
String style = "";
if(hasToolBar){
style += "border-top:none;";
}
if(hasNavBar||hasFooterBar){
style += "border-bottom:none;";
}
Integer height = (Integer)map.get(ComponentConfig.PROPERTITY_HEIGHT);
int sh = 0;
if(hasToolBar) sh +=25;
if(hasFooterBar) sh +=26;
if(hasNavBar) sh +=navbarHeight;
map.put(TABLE_HEIGHT, new Integer(height.intValue()-sh)<rowHeight*2?rowHeight*2:new Integer(height.intValue()-sh));
String rowRenderer = gc.getRowRenderer();
if(rowRenderer!=null) addConfig(GridConfig.PROPERTITY_ROW_RENDERER, rowRenderer);
if(!gc.isAutoFocus()) addConfig(GridConfig.PROPERTITY_AUTO_FOCUS, Boolean.valueOf(gc.isAutoFocus()));
addConfig(GridConfig.PROPERTITY_AUTO_APPEND, Boolean.valueOf(gc.isAutoAppend(mDefaultAutoAppend)));
addConfig(GridConfig.PROPERTITY_SUBMASK, gc.getSubMask(mDefaultGridSubmask));
addConfig(GridConfig.PROPERTITY_CAN_PASTE, Boolean.valueOf(gc.isCanPaste()));
addConfig(GridConfig.PROPERTITY_CAN_WHEEL, Boolean.valueOf(gc.isCanWheel()));
addConfig(GridConfig.PROPERTITY_GROUP_SELECT, Boolean.valueOf(gc.isGroupSelect()));
addConfig(GridConfig.PROPERTITY_ROW_HEIGHT, Integer.valueOf(rowHeight));
addConfig(GridConfig.PROPERTITY_AUTO_SHOW_FILTER, Boolean.valueOf(isAutoShowFilter));
addConfig("headheight", Integer.valueOf(headHeight));
addConfig("navbarheight", Integer.valueOf(navbarHeight));
addConfig(GridConfig.PROPERTITY_TITLE, gc.getTitle());
map.put(GridConfig.PROPERTITY_TITLE, gc.getTitle());
map.put(ROW_HEIGHT,Integer.valueOf(rowHeight));
map.put("type","hap");
processRowNumber(map,view);
processSelectable(map,view);
createGridColumns(map,view,session,model);
if(hasFooterBar)creatFooterBar(session, context);
map.put("gridstyle", style);
createGridEditors(session,context);
}
@SuppressWarnings("unchecked")
private void processRowNumber(Map map,CompositeMap view){
GridConfig gc = GridConfig.getInstance(view);
Boolean showRowNumber = gc.isShowRowNumber();
map.put(GridConfig.PROPERTITY_SHOW_ROWNUMBER, showRowNumber);
addConfig(GridConfig.PROPERTITY_SHOW_ROWNUMBER, showRowNumber);
}
@SuppressWarnings("unchecked")
private void processSelectable(Map map,CompositeMap view){
GridConfig gc = GridConfig.getInstance(view);
Boolean selectable = view.getBoolean(DataSetConfig.PROPERTITY_SELECTABLE,false);
Boolean showCheckAll = view.getBoolean(DataSetConfig.PROPERTITY_SHOW_CHECKALL,true);
String selectionmodel = view.getString(DataSetConfig.PROPERTITY_SELECTION_MODEL,"multiple");
CompositeMap root = view.getRoot();
List list = CompositeUtil.findChilds(root, "dataSet");
if(list!=null){
String dds = gc.getBindTarget();
Iterator it = list.iterator();
while(it.hasNext()){
CompositeMap ds = (CompositeMap)it.next();
String id = ds.getString(ComponentConfig.PROPERTITY_ID, "");
if("".equals(id)) {
id= IDGenerator.getInstance().generate();
}
if(id.equals(dds)){
selectable = Boolean.valueOf(ds.getBoolean(DataSetConfig.PROPERTITY_SELECTABLE, false));
showCheckAll = Boolean.valueOf(ds.getBoolean(DataSetConfig.PROPERTITY_SHOW_CHECKALL, true));
selectionmodel = ds.getString(DataSetConfig.PROPERTITY_SELECTION_MODEL, "multiple");
break;
}
}
}
map.put(DataSetConfig.PROPERTITY_SELECTABLE, selectable);
map.put(DataSetConfig.PROPERTITY_SHOW_CHECKALL, showCheckAll);
map.put(DataSetConfig.PROPERTITY_SELECTION_MODEL, selectionmodel);
addConfig(DataSetConfig.PROPERTITY_SELECTABLE, selectable);
addConfig(DataSetConfig.PROPERTITY_SELECTION_MODEL, selectionmodel);
}
@SuppressWarnings("unchecked")
private void createGridColumns(Map map, CompositeMap view,BuildSession session,CompositeMap model){
JSONArray jsons = new JSONArray();
List cols = new ArrayList();
Map lkpro = new HashMap();
lkpro.put(LOCK_WIDTH, new Integer(0));
lkpro.put(ROW_SPAN, new Integer(1));
Map ukpro = new HashMap();
ukpro.put(ROW_SPAN, new Integer(1));
CompositeMap columns = view.getChild(GridConfig.PROPERTITY_COLUMNS);
List lks = new ArrayList();
List uks = new ArrayList();
List locks = new ArrayList();
List unlocks = new ArrayList();
int maxRow =1;
int rowcheckwidth = isBestseller?70:25;
if(isHap){
rowcheckwidth = 39;
}
Integer height = (Integer)map.get(TABLE_HEIGHT);
Integer width = (Integer)map.get(ComponentConfig.PROPERTITY_WIDTH);
Integer viewWidth = (Integer)map.get(ComponentConfig.PROPERTITY_OLD_WIDTH);
float bl = 1;
//TODO:判断,如果column的宽度之和小于总宽度就同比放大
GridConfig gc = GridConfig.getInstance(view);
boolean isAutoAdjust = gc.isAutoAdjust(mDefaultAutoAdjustGrid);
String bindTarget = gc.getBindTarget();//view.getString(ComponentConfig.PROPERTITY_BINDTARGET);
if(isAutoAdjust)
if(viewWidth!=null && viewWidth.intValue() !=0) bl = (width.floatValue()/viewWidth.floatValue());
if(columns != null) {
boolean showRowNumber = ((Boolean)map.get(GridConfig.PROPERTITY_SHOW_ROWNUMBER)).booleanValue();
if(showRowNumber) {
CompositeMap column = new CompositeMap("column");
column.setNameSpaceURI(LeafApplication.LEAF_FRAMEWORK_NAMESPACE);
column.putBoolean(GridColumnConfig.PROPERTITY_LOCK,true);
column.putInt(ComponentConfig.PROPERTITY_WIDTH, isBestseller||isHlsDefault?70:35);
column.putString(GridColumnConfig.PROPERTITY_ALIGN, "center");
column.putBoolean(GridColumnConfig.PROPERTITY_RESIZABLE,false);
column.putBoolean(GridColumnConfig.PROPERTITY_SORTABLE,false);
column.putString(GridColumnConfig.PROPERTITY_PROMPT,isBestseller?"序号":"#");
column.putString(GridColumnConfig.PROPERTITY_RENDERER, "Leaf.RowNumberRenderer");
column.putString(COLUMN_TYPE,TYPE_ROW_NUMBER);
lks.add(column);
}
boolean selectable = ((Boolean)map.get(DataSetConfig.PROPERTITY_SELECTABLE)).booleanValue();
String selectmodel = (String)map.get(DataSetConfig.PROPERTITY_SELECTION_MODEL);
if(selectable) {
CompositeMap column = new CompositeMap("column");
column.setNameSpaceURI(LeafApplication.LEAF_FRAMEWORK_NAMESPACE);
column.putBoolean(GridColumnConfig.PROPERTITY_LOCK,true);
column.putInt(ComponentConfig.PROPERTITY_WIDTH, rowcheckwidth);
column.putBoolean(GridColumnConfig.PROPERTITY_RESIZABLE,false);
column.putBoolean(GridColumnConfig.PROPERTITY_SORTABLE,false);
if("multiple".equals(selectmodel)) {
column.putString(COLUMN_TYPE,TYPE_ROW_CHECKBOX);
}else{
column.putString(COLUMN_TYPE,TYPE_ROW_RADIO);
}
lks.add(column);
}
Iterator cit = columns.getChildIterator();
while(cit != null && cit.hasNext()){
CompositeMap column = (CompositeMap)cit.next();
boolean isLock = column.getBoolean(GridColumnConfig.PROPERTITY_LOCK, false);
if(isLock){
lks.add(column);
}else{
uks.add(column);
}
}
processColumns(null, lks, locks, lkpro);
processColumns(null, uks, unlocks, ukpro);
int lr = ((Integer)lkpro.get(ROW_SPAN)).intValue();
int ur = ((Integer)ukpro.get(ROW_SPAN)).intValue();
if(ur >= lr){
maxRow = ur;
ukpro.put(MAX_ROWS, new Integer(maxRow));
ukpro.put(ROW_HEIGHT, new Integer(headHeight));
lkpro.put(MAX_ROWS, new Integer(maxRow));
lkpro.put(ROW_HEIGHT, lr == 0 ? new Integer(headHeight) : new Integer(ur*headHeight/lr));
} else{
maxRow = lr;
lkpro.put(MAX_ROWS, new Integer(maxRow));
ukpro.put(MAX_ROWS, new Integer(maxRow));
lkpro.put(ROW_HEIGHT, new Integer(headHeight));
ukpro.put(ROW_HEIGHT, ur == 0 ? new Integer(headHeight) : new Integer(lr*headHeight/ur));
}
List lkFirstList = (List)lkpro.get("l1");
if(lkFirstList!=null) {
Iterator lfit = lkFirstList.iterator();
while(lfit.hasNext()){
CompositeMap column = (CompositeMap)lfit.next();
column.put(ROW_SPAN, lkpro.get(MAX_ROWS));
addRowSpan(column);
}
}
List ukFirstList = (List)ukpro.get("l1");
if(ukFirstList!=null) {
Iterator ufit = ukFirstList.iterator();
while(ufit.hasNext()){
CompositeMap column = (CompositeMap)ufit.next();
column.put(ROW_SPAN, ukpro.get(MAX_ROWS));
addRowSpan(column);
}
}
cols.addAll(locks);
cols.addAll(unlocks);
Iterator it = cols.iterator();
while(it.hasNext()){
CompositeMap column = (CompositeMap)it.next();
if(column.getChilds() == null){
GridColumnConfig gcc = GridColumnConfig.getInstance(column);
String dataindex = gcc.getName();
if(!"".equals(dataindex))
column.putString(GridColumnConfig.PROPERTITY_NAME, dataindex);
column.putBoolean(GridColumnConfig.PROPERTITY_LOCK, gcc.isLock());
boolean hidden = gcc.isHidden();
if(hidden)
column.putBoolean(GridColumnConfig.PROPERTITY_VISIABLE, false);
if(gcc.isGroup())
column.putBoolean(GridColumnConfig.PROPERTITY_GROUP, true);
if(gcc.isShowTitle(model))
column.putBoolean(GridColumnConfig.PROPERTITY_SHOW_TITLE, true);
column.putBoolean(GridColumnConfig.PROPERTITY_HIDDEN, hidden);
column.putBoolean(GridColumnConfig.PROPERTITY_RESIZABLE, gcc.isResizable());
column.putBoolean(GridColumnConfig.PROPERTITY_SORTABLE, gcc.isSortable());
column.putBoolean(GridColumnConfig.PROPERTITY_FOR_EXPORT, gcc.isForExport(!hidden && column.getString(COLUMN_TYPE)==null?true:false));
boolean autoAdjust = gcc.isAutoAdjust(mDefaultAutoAdjustGridColumn);
if(autoAdjust)
column.putBoolean(GridColumnConfig.PROPERTITY_AUTO_ADJUST, true);
column.putInt(GridColumnConfig.PROPERTITY_MAX_ADJUST_WIDTH, gcc.getMaxAdjustWidth());
column.putString(GridColumnConfig.PROPERTITY_PROMPT,session.getLocalizedPrompt(TextParser.parse(column.getString(GridColumnConfig.PROPERTITY_PROMPT,getFieldPrompt(session, column, bindTarget)),model)));
column.putString(GridColumnConfig.PROPERTITY_FULL_PROMPT,session.getLocalizedPrompt(TextParser.parse(column.getString(GridColumnConfig.PROPERTITY_FULL_PROMPT,getFieldFullPrompt(session, column, bindTarget)),model)));
String editorFunction = gcc.getEditorFunction();
if(editorFunction!=null)
column.put(GridColumnConfig.PROPERTITY_EDITOR_FUNCTION, TextParser.parse(editorFunction, model));
float cwidth = gcc.getWidth();
String type = column.getString(COLUMN_TYPE);
if(!"rowcheck".equals(type) && !"rowradio".equals(type)&& !"rownumber".equals(type) && autoAdjust)
cwidth = cwidth * bl;
column.putInt(GridColumnConfig.PROPERTITY_WIDTH, Math.round(cwidth));
String editor = gcc.getEditor(model);
if(!"".equals(editor)){
if(isCheckBoxEditor(editor, view)){
column.putString(COLUMN_TYPE, TYPE_CELL_CHECKBOX);
}
column.put(GridColumnConfig.PROPERTITY_EDITOR, editor);
}
String renderer = gcc.getRenderer(model);
if(!"".equals(renderer))
column.put(GridColumnConfig.PROPERTITY_RENDERER, renderer);
String footerRenderer = gcc.getFooterRenderer(model);
if(!"".equals(footerRenderer))
column.put(GridColumnConfig.PROPERTITY_FOOTER_RENDERER, footerRenderer);
String exportDataType = gcc.getExportDataType(model);
if(!"".equals(exportDataType))
column.put(GridColumnConfig.PROPERTITY_EXPORT_DATA_TYPE, exportDataType);
if(gcc.isFilterable()){
hasFilter = true;
column.put(GridColumnConfig.PROPERTITY_FILTERABLE, true);
}
toJSONForParentColumn(column,session,model,bindTarget);
JSONObject json = new JSONObject(column);
jsons.put(json);
}
}
}
// map.put(ComponentConfig.PROPERTITY_BINDTARGET, bindTarget);
map.put(HEAD_HEIGHT, new Integer(maxRow*headHeight));
map.put(LOCK_COLUMNS, locks);
map.put(UNLOCK_COLUMNS, unlocks);
map.put(HTML_LOCKAREA, generateLockArea(map, locks, lkpro,session, bindTarget,model));
map.put(HTML_UNLOCKAREA, generateUnlockArea(map, unlocks, ukpro,session, bindTarget,model));
Integer lockWidth = (Integer)lkpro.get(LOCK_WIDTH);
Integer unlockWidth = (Integer)ukpro.get(UNLOCK_WIDTH);
map.put(LOCK_WIDTH, lockWidth);
map.put(UNLOCK_WIDTH, new Integer(width.intValue()-lockWidth.intValue()));
if(isBestseller){
map.put("unlockheadwidth", new Integer(width.intValue() - lockWidth.intValue()-(lockWidth.intValue() == 0 ?2:1)));
map.put("unlockbodywidth", new Integer(width.intValue() - lockWidth.intValue()-2));
}
int bodyHeight = height.intValue()-maxRow*headHeight;
if(hasFilter && isAutoShowFilter){
bodyHeight -= headHeight;
}
if((session.getTheme().toUpperCase().indexOf("HAP") != -1)&&hasFooterBar){
bodyHeight = bodyHeight-1;
}
map.put(BODY_HEIGHT, new Integer(bodyHeight));
map.put(ROW_WIDTH,lockWidth + unlockWidth);
addConfig(GridConfig.PROPERTITY_COLUMNS, jsons);
addConfig(ComponentConfig.PROPERTITY_WIDTH, map.get(ComponentConfig.PROPERTITY_WIDTH));
addConfig(ComponentConfig.PROPERTITY_HEIGHT, map.get(ComponentConfig.PROPERTITY_HEIGHT));
addConfig("rowcheckwidth", rowcheckwidth);
map.put(CONFIG, getConfigString());
}
private void toJSONForParentColumn(CompositeMap column,BuildSession session,CompositeMap model,String bindTarget){
CompositeMap parent=null;
if(column.get("_parent") instanceof CompositeMap){
parent=(CompositeMap) column.get("_parent");
if(parent!=null){
if(!parent.getBoolean(GridColumnConfig.PROPERTITY_FOR_EXPORT, true))
parent.putBoolean(GridColumnConfig.PROPERTITY_FOR_EXPORT, parent.getBoolean(GridColumnConfig.PROPERTITY_FOR_EXPORT, true));
parent.putString(GridColumnConfig.PROPERTITY_PROMPT,session.getLocalizedPrompt(TextParser.parse(parent.getString(GridColumnConfig.PROPERTITY_PROMPT,getFieldPrompt(session, column, bindTarget)),model)));
parent.putString(GridColumnConfig.PROPERTITY_FULL_PROMPT,session.getLocalizedPrompt(TextParser.parse(parent.getString(GridColumnConfig.PROPERTITY_FULL_PROMPT,getFieldFullPrompt(session, column, bindTarget)),model)));
toJSONForParentColumn(parent,session,model,bindTarget);
column.put("_parent", new JSONObject(parent));
}
}
}
@SuppressWarnings("unchecked")
private void createGridEditors(BuildSession session, ViewContext context) throws IOException{
CompositeMap view = context.getView();
Map map = context.getMap();
CompositeMap model = context.getModel();
CompositeMap editors = view.getChild(GridConfig.PROPERTITY_EDITORS);
StringBuilder sb = new StringBuilder();
if(hasFilter){
CompositeMap filterEditor = new CompositeMap("textField");
filterEditor.setNameSpaceURI(LeafApplication.LEAF_FRAMEWORK_NAMESPACE);
filterEditor.put(TextFieldConfig.PROPERTITY_ID, map.get(GridConfig.PROPERTITY_ID)+"_filter_editor");
if(editors == null){
editors = view.createChild(GridConfig.PROPERTITY_EDITORS);
}
editors.addChild(filterEditor);
}
if(editors != null && editors.getChilds() != null) {
Iterator it = editors.getChildIterator();
while(it.hasNext()){
CompositeMap editor = (CompositeMap)it.next();
editor.put(ComponentConfig.PROPERTITY_IS_CUST, Boolean.FALSE);
editor.put(ComponentConfig.PROPERTITY_STYLE, "position:absolute;z-index:2;left:-1000px;top:-1000px;");
try {
sb.append(session.buildViewAsString(model, editor));
} catch (Exception e) {
throw new IOException(e);
}
}
}
map.put("editors", sb.toString());
}
@SuppressWarnings("unchecked")
private boolean isCheckBoxEditor(String id, CompositeMap view){
boolean isChecBox = false;
CompositeMap editors = view.getChild(GridConfig.PROPERTITY_EDITORS);
if(editors != null && editors.getChilds() != null) {
Iterator it = editors.getChildIterator();
while(it.hasNext()){
CompositeMap editor = (CompositeMap)it.next();
String eid = editor.getString(ComponentConfig.PROPERTITY_ID,"");
if(id.equals(eid)&& "checkBox".equals(editor.getName())){
isChecBox = true;
break;
}
}
}
return isChecBox;
}
@SuppressWarnings("unchecked")
private boolean creatToolBar(BuildSession session, ViewContext context) throws IOException{
CompositeMap view = context.getView();
Map map = context.getMap();
CompositeMap model = context.getModel();
CompositeMap toolbar = view.getChild(GridConfig.PROPERTITY_TOOLBAR);
String dataset = (String)map.get(ComponentConfig.PROPERTITY_BINDTARGET);
StringBuilder sb = new StringBuilder();
boolean hasToolBar = false;
String title = (String) view.get(GridConfig.PROPERTITY_TITLE);
//modify by niminmin grid默认增加全局excel导出
String excelBUttonFLag=ConfigUtils.getProperty(LEAF_EXCEL_BUTTON);
if("true".equalsIgnoreCase(excelBUttonFLag)){
if (toolbar == null || toolbar.getChilds() == null) {
toolbar = new CompositeMap(GridConfig.PROPERTITY_TOOLBAR);
CompositeMap excelBtn = new CompositeMap(COMPONENT_BUTTON);
excelBtn.setNameSpaceURI(LeafApplication.LEAF_FRAMEWORK_NAMESPACE);
//设置按钮类型type为 excel
excelBtn.put(COLUMN_TYPE, TYPE_EXCEL);
excelBtn.setName(COMPONENT_BUTTON);
//添加按钮
toolbar.addChild(excelBtn);
} else {
List<CompositeMap> toolbarChilds = toolbar.getChilds();
boolean excelFlag = false;
for (int i = 0; i < toolbarChilds.size(); i++) {
if (toolbarChilds.get(i) != null && toolbarChilds.get(i).get("type") != null && TYPE_EXCEL.equalsIgnoreCase(toolbarChilds.get(i).get("type").toString())) {
excelFlag = true;
}
}
if (!excelFlag) {
CompositeMap excelBtn = new CompositeMap(COMPONENT_BUTTON);
excelBtn.setNameSpaceURI(LeafApplication.LEAF_FRAMEWORK_NAMESPACE);
excelBtn.put(COLUMN_TYPE, TYPE_EXCEL);
excelBtn.setName(COMPONENT_BUTTON);
toolbar.addChild(excelBtn);
}
}
}
if((toolbar != null && toolbar.getChilds() != null)||title!=null){
hasToolBar = true;
CompositeMap tb = new CompositeMap(GridConfig.PROPERTITY_TOOLBAR);
tb.setNameSpaceURI(LeafApplication.LEAF_FRAMEWORK_NAMESPACE);
// String widthStr = view.getString(ComponentConfig.PROPERTITY_WIDTH, ""+getDefaultWidth(BuildSession session)());
// String wstr = TextParser.parse(widthStr, model);
// Integer width = Integer.valueOf("".equals(wstr) ? "150" : wstr);
Integer width = (Integer)map.get(ComponentConfig.PROPERTITY_WIDTH);
tb.put(ComponentConfig.PROPERTITY_ID, map.get(ComponentConfig.PROPERTITY_ID)+"_tb");
if(isHap){
tb.put(ComponentConfig.PROPERTITY_WIDTH,width);
tb.put(ComponentConfig.PROPERTITY_HEIGHT, -1);
}else {
tb.put(ComponentConfig.PROPERTITY_WIDTH, Integer.valueOf(isHlsDefault ? 34 : -1));
tb.put(ComponentConfig.PROPERTITY_HEIGHT, Integer.valueOf(isHlsDefault ? -1 : 25));
}
tb.put(ComponentConfig.PROPERTITY_CLASSNAME, "grid-toolbar");
if(title!=null){
CompositeMap titleDiv = new CompositeMap("div");
titleDiv.put("class","grid-toolbar-title");
titleDiv.setText(title);
tb.addChild(titleDiv);
}
if(toolbar != null && toolbar.getChilds() != null) {
Iterator it = toolbar.getChildIterator();
while(it.hasNext()){
CompositeMap item = (CompositeMap)it.next();
// item.put(ComponentConfig.PROPERTITY_IS_CUST, Boolean.FALSE);
if("button".equals(item.getName())){
String type = item.getString("type");
String fileName = TextParser.parse(item.getString("filename",""),model);
String path = model.getObject("/request/@context_path").toString();
String imagePath = null;
String buttonTextstyle=null;
String iconStyle=null;
String btnStyle = null;
String topButtonStyle=null;
if(type!=null){
if(isHap){
imagePath = path+"/leafresource/leaf.ui.std/"+session.getTheme().toLowerCase()+"/button/";
imagePath = imagePath+"hlsgrid"+type.toLowerCase()+".png";
iconStyle = "line-height: 24px;height: 24px;width:24px;font-size: 12px;background-repeat:no-repeat;background-position: center;background-image:url("+imagePath+");float:left;";
buttonTextstyle = "margin-left: 3px;font-size: 12px;text-align: left;background-image: none;";
String color = "color:#fff;";
String backgroundSize = "background-size: 16px;";
String border = "border:1px solid #889DAC!important;";
/*if("query".equalsIgnoreCase(type)){
color = "color:#E3B286;";
border = "border:1px solid #E3B286!important;";
}else if("excel".equalsIgnoreCase(type)){
backgroundSize = "background-size: 14px;";
color = "color:#6B93C4;";
border = "border:1px solid #6B93C4!important;";
}else if("save".equalsIgnoreCase(type)){
backgroundSize = "background-size: 16px;";
color = "color:#7FAA82;";
border = "border:1px solid #7FAA82!important;";
}else if("delete".equalsIgnoreCase(type)){
color = "color:#DF7979;";
border = "border:1px solid #DF7979!important;";
}else if("add".equalsIgnoreCase(type)){
color = "color:#889DAC;";
border = "border:1px solid #889DAC!important;";
}else if("clear".equalsIgnoreCase(type)){
color = "color:#ECCCB8;";
border = "border:1px solid #ECCCB8!important;";
}else{
color = "color:#889DAC;";
}*/
buttonTextstyle = buttonTextstyle+color;
iconStyle = iconStyle+color+backgroundSize;
/*topButtonStyle = "padding-left:2px;padding-right:5px;"+ border;*/
topButtonStyle = "padding-left:2px;padding-right:5px;background: #5A7FFF;border-radius: 2px;";
}
if("query".equalsIgnoreCase(type)){
item = createButton(item,session.getLocalizedPrompt("HAP_QUERY"),"grid-btn grid-query grid-btn-hap-toolbar",buttonTextstyle,"",iconStyle,btnStyle,topButtonStyle);
}else if("filter".equalsIgnoreCase(type)){
item = createButton(item,session.getLocalizedPrompt("HAP_NEW"),"grid-btn grid-filter grid-btn-hap-toolbar",buttonTextstyle,"function(){$('"+map.get(ComponentConfig.PROPERTITY_ID)+"').toggleFilter()}",iconStyle,btnStyle,topButtonStyle);
}else if("add".equalsIgnoreCase(type)){
item = createButton(item,session.getLocalizedPrompt("HAP_NEW"),"grid-btn grid-add grid-btn-hap-toolbar",buttonTextstyle,"function(){$('"+dataset+"').create()}",iconStyle,btnStyle,topButtonStyle);
}else if("delete".equalsIgnoreCase(type)){
item = createButton(item,session.getLocalizedPrompt("HAP_DELETE"),"grid-btn grid-delete grid-btn-hap-toolbar",buttonTextstyle,"function(){$('"+map.get(ComponentConfig.PROPERTITY_ID)+"').remove()}",iconStyle,btnStyle,topButtonStyle);
}else if("save".equalsIgnoreCase(type)){
item = createButton(item,session.getLocalizedPrompt("HAP_SAVE"),"grid-btn grid-save grid-btn-hap-toolbar",buttonTextstyle,"function(){$('"+dataset+"').submit()}",iconStyle,btnStyle,topButtonStyle);
}else if("clear".equalsIgnoreCase(type)){
item = createButton(item,session.getLocalizedPrompt("HAP_CLEAR"),"grid-btn grid-clear grid-btn-hap-toolbar",buttonTextstyle,"function(){$('"+map.get(ComponentConfig.PROPERTITY_ID)+"').clear()}",iconStyle,btnStyle,topButtonStyle);
}else if("excel".equalsIgnoreCase(type)){
item = createButton(item,session.getLocalizedPrompt("HAP_EXPORT"),"grid-btn grid-excel grid-btn-hap-toolbar",buttonTextstyle,"function(){$('"+map.get(ComponentConfig.PROPERTITY_ID)+"')._export('xls','"+fileName+"')}",iconStyle,btnStyle,topButtonStyle);
}else if("excelmemo".equalsIgnoreCase(type)){
item = createButton(item,session.getLocalizedPrompt("HAP_EXPORT"),"grid-btn grid-excel grid-btn-hap-toolbar",buttonTextstyle,"function(){$('"+map.get(ComponentConfig.PROPERTITY_ID)+"')._export('xls_memory','"+fileName+"')}",iconStyle,btnStyle,topButtonStyle);
}else if("excel2007".equalsIgnoreCase(type)){
item = createButton(item,session.getLocalizedPrompt("HAP_EXPORT"),"grid-btn grid-excel2007 grid-btn-hap-toolbar",buttonTextstyle,"function(){$('"+map.get(ComponentConfig.PROPERTITY_ID)+"')._export('xlsx','"+fileName+"')}",iconStyle,btnStyle,topButtonStyle);
}else if("txt".equalsIgnoreCase(type)){
item = createButton(item,session.getLocalizedPrompt("HAP_EXPORT"),"grid-btn grid-txt grid-btn-hap-toolbar",buttonTextstyle,"function(){$('"+map.get(ComponentConfig.PROPERTITY_ID)+"')._export('txt','"+fileName+"')}",iconStyle,btnStyle,topButtonStyle);
}else if("customize".equalsIgnoreCase(type)){
item = createButton(item,session.getLocalizedPrompt("HAP_CUST"),"grid-btn grid-cust grid-btn-hap-toolbar",buttonTextstyle,"function(){$('"+map.get(ComponentConfig.PROPERTITY_ID)+"').customize('"+path+"')}",iconStyle,btnStyle,topButtonStyle);
}else{
item = createButton(item,item.getText(),"grid-btn grid-cust grid-btn-hap-toolbar",buttonTextstyle,null,iconStyle,btnStyle,topButtonStyle);
}
}else{
if(isHap){
topButtonStyle = "padding-left:2px;padding-right:5px;background-color:#5A7FFF;border-radius: 2px;";
iconStyle = "line-height: 24px;height: 24px;margin-left: 2px;font-size: 12px;color:#889DAC;background-size: 18px;background-repeat:no-repeat;background-position: center;float:left;";
buttonTextstyle = "margin-left: 3px;font-size: 12px;text-align: center;color:#FFF;background-image: none;";
if(item.get(ButtonConfig.PROPERTITY_ICON_STYLE)!=null&&item.get(ButtonConfig.PROPERTITY_ICON_STYLE).toString().indexOf("background-image")!=-1){
iconStyle =iconStyle+"width:24px;";
buttonTextstyle =buttonTextstyle+"padding-left:20px;text-align: left;";
}
btnStyle = "color:#889DAC;";
item.put(ButtonConfig.PROPERTITY_ICON_STYLE,iconStyle+item.get(ButtonConfig.PROPERTITY_ICON_STYLE));
item.put(ButtonConfig.PROPERTITY_BUTTON_STYLE,buttonTextstyle+item.get(ButtonConfig.PROPERTITY_BUTTON_STYLE));
item.put(ButtonConfig.PROPERTITY_STYLE,btnStyle+item.get(ButtonConfig.PROPERTITY_STYLE));
item.put(ButtonConfig.PROPERTITY_BUTTON_CLASS,"grid-btn grid-cust grid-btn-hap-toolbar");
item.put(ButtonConfig.PROPERTITY_TOP_BUTTON_STYLE,topButtonStyle);
}
}
}
// tb.addChild(item);
tb.addChild(0,item);
}
if(!isHlsDefault)sb.append("<tr><td>");
try {
sb.append(session.buildViewAsString(model, tb));
} catch (Exception e) {
throw new IOException(e);
}
if(!isHlsDefault)sb.append("</td></tr>");
}
}
map.put(GridConfig.PROPERTITY_TOOLBAR, sb.toString());
return hasToolBar;
}
private CompositeMap createButton(CompositeMap button, String text, String clz,String buttonTextstyle,String function){
if("".equals(button.getString(ButtonConfig.PROPERTITY_ICON,""))){
button.put(ButtonConfig.PROPERTITY_ICON, "null");
button.put(ButtonConfig.PROPERTITY_BUTTON_CLASS, clz);
button.put(ButtonConfig.PROPERTITY_BUTTON_STYLE, buttonTextstyle);
if(isHlsDefault){
button.put(ButtonConfig.PROPERTITY_WIDTH, 34);
button.put(ButtonConfig.PROPERTITY_HEIGHT, 29);
}
if(isHap){
button.put(ButtonConfig.PROPERTITY_WIDTH, 24);
button.put(ButtonConfig.PROPERTITY_HEIGHT, 24);
}
}
if(!isHap){
if(isHlsDefault)
button.put(ButtonConfig.PROPERTITY_TITLE,button.getString(ButtonConfig.PROPERTITY_TEXT, text));
else
button.put(ButtonConfig.PROPERTITY_TEXT,button.getString(ButtonConfig.PROPERTITY_TEXT, text));
}else{
button.put(ButtonConfig.PROPERTITY_TEXT,button.getString(ButtonConfig.PROPERTITY_TEXT, text));
}
if(!"".equals(function))button.put(ButtonConfig.PROPERTITY_CLICK, function);
return button;
}
private CompositeMap createButton(CompositeMap button, String text, String clz,String buttonTextstyle,String function,String iconStyle,String btnStyle,String topButtonStyle){
createButton(button,text, clz,buttonTextstyle,function);
if(iconStyle!=null){
button.put(ButtonConfig.PROPERTITY_ICON_STYLE,iconStyle);
}
if(btnStyle!=null){
button.put(ButtonConfig.PROPERTITY_STYLE,(button.get(ButtonConfig.PROPERTITY_STYLE)==null?"":button.get(ButtonConfig.PROPERTITY_STYLE))+btnStyle);
}
if(topButtonStyle!=null){
button.put(ButtonConfig.PROPERTITY_TOP_BUTTON_STYLE,(button.get(ButtonConfig.PROPERTITY_TOP_BUTTON_STYLE)==null?"":button.get(ButtonConfig.PROPERTITY_TOP_BUTTON_STYLE))+topButtonStyle);
}
return button;
}
// public boolean hasFooterBar(BuildSession session, ViewContext context){
// boolean hasFooterBar = false;
// CompositeMap view = context.getView();
// GridConfig gc = GridConfig.getInstance(view);
// CompositeMap columns = gc.getColumns();
// List childs = columns.getChilds();
// if(childs!=null){
// Iterator it = childs.iterator();
// while(it.hasNext()){
// CompositeMap column = (CompositeMap)it.next();
// GridColumnConfig gcc = GridColumnConfig.getInstance(column);
// String footerRenderer = gcc.getFooterRenderer();
// if(footerRenderer!=null){
// hasFooterBar = true;
// break;
// }
// }
// }
// return hasFooterBar;
// }
@SuppressWarnings("unchecked")
public boolean hasFooterBar(CompositeMap column,CompositeMap model){
boolean hasFooterBar = false;
GridColumnConfig gcc = GridColumnConfig.getInstance(column);
String footerRenderer = gcc.getFooterRenderer(model);
if(!"".equals(footerRenderer)){
return true;
}
List childs = column.getChilds();
if(childs!=null){
Iterator it = childs.iterator();
while(it.hasNext()){
CompositeMap col = (CompositeMap)it.next();
if(hasFooterBar(col,model)){
hasFooterBar = true;
break;
}
}
}
return hasFooterBar;
}
@SuppressWarnings("unchecked")
private void creatFooterBar(BuildSession session, ViewContext context) throws IOException{
Map map = context.getMap();
int lockWidth = ((Integer)map.get(LOCK_WIDTH)).intValue();
StringBuilder sb = new StringBuilder();
sb.append("<tr><td><div class='grid-footerbar' atype='grid.fb"+"' style='width:"+map.get(ComponentConfig.PROPERTITY_WIDTH)+"px'>");
if(lockWidth!=0){
sb.append("<div atype='grid.lf' style='float:left;width:"+(lockWidth-1)+"px'>");//class='grid-la'
List locks = (List)map.get(LOCK_COLUMNS);
if(locks!=null){
sb.append("<table cellSpacing='0' cellPadding='0' border='0' atype='fb.lbt' ");
Iterator it = locks.iterator();
sb.append(createFooterBarTable(it,false));
}
sb.append("</div>");
}
sb.append("<div class='grid-ua' atype='grid.uf' style='width:"+map.get(UNLOCK_WIDTH)+"px'>");
List unlocks = (List)map.get(UNLOCK_COLUMNS);
if(unlocks!=null){
sb.append("<table cellSpacing='0' cellPadding='0' border='0' atype='fb.ubt' ");
Iterator it = unlocks.iterator();
sb.append(createFooterBarTable(it,true));
}
sb.append("</div>");
sb.append("</div></td></tr>");
map.put(FOOTER_BAR, sb.toString());
}
@SuppressWarnings("unchecked")
private String createFooterBarTable(Iterator it,boolean hasSpan){
int i = 0,w = 0;
StringBuilder sb = new StringBuilder();
StringBuilder tb = new StringBuilder();
StringBuilder th = new StringBuilder();
th.append("<tr class='grid-hl'>");
while(it.hasNext()){
CompositeMap column = (CompositeMap)it.next();
if(column.getChilds()!=null) continue;
GridColumnConfig gcc = GridColumnConfig.getInstance(column);
w += gcc.getWidth();
th.append("<th style='width:"+gcc.getWidth()+"px;' dataindex='"+gcc.getName()+"'></th>");
tb.append("<td style='text-align:"+gcc.getAlign()+";");
// tb.append(((i==0) ? "border:none;" : "")+"'");
tb.append("'");
if(!"".equals(gcc.getName())) tb.append("dataindex='"+gcc.getName()+"'");
tb.append(">&#160;</td>");
i++;
}
if(hasSpan)th.append("<th style='width:34px;'></th>");
sb.append("style='width:"+w+"px;table-layout:fixed;'>");//margin-right:20px;padding-right:20px;
sb.append(th.toString()).append("</tr><tr>");
sb.append(tb.toString());
sb.append("</tr></table>");
return sb.toString();
}
@SuppressWarnings("unchecked")
private boolean createNavgationToolBar(BuildSession session, ViewContext context) throws IOException{
boolean hasNavBar = false;
CompositeMap view = context.getView();
GridConfig gc = GridConfig.getInstance(view);
Map map = context.getMap();
CompositeMap model = context.getModel();
StringBuilder sb = new StringBuilder();
String dataset = (String) map.get(ComponentConfig.PROPERTITY_BINDTARGET);
boolean hasNav = gc.hasNavBar(model);
if(hasNav){
hasNavBar = true;
CompositeMap navbar = new CompositeMap("navBar");
navbar.setNameSpaceURI(LeafApplication.LEAF_FRAMEWORK_NAMESPACE);
// String widthStr = view.getString(ComponentConfig.PROPERTITY_WIDTH, ""+getDefaultWidth(BuildSession session)());
// String wstr = TextParser.parse(widthStr, model);
Integer width = (Integer)map.get(ComponentConfig.PROPERTITY_WIDTH);//Integer.valueOf("".equals(wstr) ? "150" : wstr);
// Integer width = Integer.valueOf(view.getString(ComponentConfig.PROPERTITY_WIDTH));
navbar.put(ComponentConfig.PROPERTITY_ID, map.get(ComponentConfig.PROPERTITY_ID)+"_navbar");
navbar.put(ComponentConfig.PROPERTITY_IS_CUST, Boolean.FALSE);
navbar.put(ComponentConfig.PROPERTITY_HEIGHT, new Integer(navbarHeight));
navbar.put(ComponentConfig.PROPERTITY_CLASSNAME, "grid-navbar");
// navbar.put(PROPERTITY_STYLE, "border:none;border-top:1px solid #cccccc;");
navbar.put(NavBarConfig.PROPERTITY_DATASET, dataset);
DataSetConfig dc = DataSetConfig.getInstance(getDataSet(session, dataset));
boolean autoCount = dc.isAutoCount(model,mDefaultAutoCount);
boolean infiniteLoad = dc.isInfiniteLoad(mDefaultInfiniteLoad);
navbar.put(NavBarConfig.PROPERTITY_NAVBAR_TYPE, view.getString(NavBarConfig.PROPERTITY_NAVBAR_TYPE,infiniteLoad?"infinite":autoCount?"complex":"tiny"));
navbar.put(NavBarConfig.PROPERTITY_MAX_PAGE_COUNT, new Integer(view.getInt(NavBarConfig.PROPERTITY_MAX_PAGE_COUNT,10)));
navbar.put(NavBarConfig.PROPERTITY_PAGE_SIZE_EDITABLE,Boolean.valueOf(view.getBoolean(NavBarConfig.PROPERTITY_PAGE_SIZE_EDITABLE,true)));
sb.append("<tr><td class='grid-navbar-td'>");
try {
sb.append(session.buildViewAsString(model, navbar));
} catch (Exception e) {
throw new IOException(e);
}
sb.append("</td></tr>");
map.put("navbar", sb.toString());
}
return hasNavBar;
}
@SuppressWarnings("unchecked")
private void processColumns(CompositeMap parent, List children, List cols, Map pro){
Iterator it = children.iterator();
boolean plock =parent!=null? (parent.getBoolean(GridColumnConfig.PROPERTITY_LOCK) != null ? parent.getBoolean(GridColumnConfig.PROPERTITY_LOCK).booleanValue() : false ):false;
while(it.hasNext()){
CompositeMap column = (CompositeMap)it.next();
if(plock)
column.putBoolean(GridColumnConfig.PROPERTITY_LOCK, true);
int level;
if(parent == null){
level = 1;
}else{
level = parent.getInt("_level").intValue() + 1;
}
int rows = ((Integer)pro.get(ROW_SPAN)).intValue();
if(level>rows)pro.put(ROW_SPAN, new Integer(level));
column.put("_level", new Integer(level));
column.put("_parent", parent);
List hlist = (List)pro.get("l"+level);
if(hlist == null){
hlist = new ArrayList();
pro.put("l"+level, hlist);
}
hlist.add(column);
cols.add(column);
if(column.getChilds() != null && column.getChilds().size() >0){
processColumns(column, column.getChilds(), cols, pro);
}else{
addColSpan(column);
}
}
}
@SuppressWarnings("unchecked")
private void addRowSpan(CompositeMap column){
List children = column.getChilds();
Integer psp = column.getInt(ROW_SPAN);
if(children != null && children.size() >0){
minusRowSpan(column);
Iterator it = children.iterator();
while(it.hasNext()){
CompositeMap child = (CompositeMap)it.next();
child.put(ROW_SPAN, new Integer(psp.intValue()-1));
addRowSpan(child);
}
}
}
private void minusRowSpan(CompositeMap column){
if(column == null)return;
Integer rowspan = column.getInt(ROW_SPAN);
if(rowspan != null){
int cs = Math.max(rowspan.intValue() -1,1);
column.put(ROW_SPAN, new Integer(cs));
}
CompositeMap parent = (CompositeMap)column.get("_parent");
if(parent != null){
minusRowSpan(parent);
}
}
private void addColSpan(CompositeMap column){
if(column == null)return;
CompositeMap parent = (CompositeMap)column.get("_parent");
if(parent != null){
Integer colspan = parent.getInt(COL_SPAN);
if(colspan == null){
parent.put(COL_SPAN, new Integer(1));
}else{
int cs = colspan.intValue() +1;
parent.put(COL_SPAN, new Integer(cs));
}
}
addColSpan(parent);
}
@SuppressWarnings("unchecked")
private String generateLockArea(Map map, List columns, Map pro,BuildSession session, String dataSet, CompositeMap model){
StringBuilder sb = new StringBuilder();
StringBuilder th = new StringBuilder();
StringBuilder filter = new StringBuilder("");
boolean hasLockColumn = false;
Integer rows = (Integer)pro.get(ROW_SPAN);
Iterator it = columns.iterator();
int lockWidth = 0;
int row_height = ((Integer) pro.get(ROW_HEIGHT))==null?0:((Integer) pro.get(ROW_HEIGHT)).intValue();
while(it.hasNext()){
CompositeMap column = (CompositeMap)it.next();
GridColumnConfig gcc = GridColumnConfig.getInstance(column);
if(gcc.isLock()){
hasLockColumn = true;
List children = column.getChilds();
if(children == null){
boolean hidden = gcc.isHidden();
if(hidden) continue;
float cwidth = hidden? 0 : gcc.getWidth();
th.append("<th style='width:"+cwidth+"px;' dataindex='"+gcc.getName()+"'></th>");
lockWidth +=cwidth;
}
}
}
pro.put(LOCK_WIDTH, new Integer(lockWidth));
if(hasLockColumn){
sb.append("<DIV class='grid-la' atype='grid.lc' style='width:"+(lockWidth-1)+"px;'>")
.append("<DIV class='grid-lh' atype='grid.lh' unselectable='on' onselectstart='return false;' style='height:"+rows.intValue()*((Integer)pro.get(ROW_HEIGHT)).intValue()+"px;'>");
filter.append("<div class='grid-lfi' atype='grid.lfi' style='width:"+(lockWidth-1)+"px;");
filter.append("'>");
StringBuilder hsb = new StringBuilder();
int finnalRowHeight = row_height;
filter.append("<table cellSpacing='0' atype='grid.lfit' cellPadding='0' border='0' style='width:"+lockWidth+"px'><TBODY>")
.append("<tr class='grid-hl'>")
.append(th.toString())
.append("</tr>")
.append("<tr style=\"height:"+finnalRowHeight+"px;line-height:"+(row_height-6)+"px\">");
for(int i=1,len = rows.intValue();i<=len;i++){
List list = (List)pro.get("l"+i);
hsb.append("<TR style=\"height:"+finnalRowHeight+"px;line-height:"+(row_height-6)+"px\">");
if(list!=null) {
Iterator lit = list.iterator();
while(lit.hasNext()){
CompositeMap column = (CompositeMap)lit.next();
GridColumnConfig gcc = GridColumnConfig.getInstance(column);
String ct = column.getString(COLUMN_TYPE);
boolean showCheckAll = isBestseller?false:((Boolean) map.get(DataSetConfig.PROPERTITY_SHOW_CHECKALL)).booleanValue();
if(TYPE_ROW_CHECKBOX.equals(ct)){
if(showCheckAll){
hsb.append("<TD class='grid-hc' atype='grid.rowcheck' style='height:"+finnalRowHeight+"px;' rowspan='"+column.getInt(ROW_SPAN)+"'><div atype='grid.headcheck' style='margin:auto' class='grid-ckb item-ckb-u'></div></TD>");
}else{
hsb.append("<TD class='grid-hc' atype='grid.rowcheck' style='height:"+finnalRowHeight+"px;' rowspan='"+column.getInt(ROW_SPAN)+"'>");
if(isBestseller){
hsb.append("<center><div atype='grid.headcheck'>全选</div></center>");
}
hsb.append("</TD>");
}
if(i == len)
filter.append("<td><div class='grid-filter-icon'></div></td>");
}else if(TYPE_ROW_RADIO.equals(ct)) {
hsb.append("<TD class='grid-hc' atype='grid.rowradio' style='height:"+finnalRowHeight+"px;' rowspan='"+column.getInt(ROW_SPAN)+"'><div>&nbsp;</div></TD>");
if(i == len)
filter.append("<td></td>");
}else{
boolean hidden = gcc.isHidden();
if(hidden) continue;
String prompt = getFieldPrompt(session, column, dataSet);
String fullPrompt = getFieldFullPrompt(session, column, dataSet);
if("".equals(fullPrompt)){
fullPrompt = prompt;
}
String headTitle = session.getLocalizedPrompt(prompt);
if(headTitle!=null && headTitle.equals(prompt)){
headTitle = TextParser.parse(prompt, model);
}
hsb.append("<TD title='"+fullPrompt+"' class='grid-hc' atype='grid.head' style='height:"+finnalRowHeight+"px;visibility:"+(hidden?"hidden":"")+"' colspan='"+column.getInt(COL_SPAN,1)+"' rowspan='"+column.getInt(ROW_SPAN)+"' dataindex='"+gcc.getName()+"'><div");
if(gcc.getHeadStyle() != null){
hsb.append(" style='").append(gcc.getHeadStyle()).append("'");
}
hsb.append(">");
//必填
if(gcc.isRequired()){
hsb.append("<span class='prompt-required prompt-required-show' title='"+gcc.getName()+"'>*</span>");
}
hsb.append(headTitle);
if(gcc.isFilterable()){
hsb.append("<input class='grid-filter-icon' tabIndex='-1' disabled>");
}
//筛选
if(gcc.isSortable()){
hsb.append("<span class='sort-btn'></span>");
}
hsb.append("</div></TD>");
if(i == len){
if(gcc.isFilterable())
filter.append("<td atype=\"grid-filter\" dataindex=\""+gcc.getName()+"\"><div class='grid-cell cell-editor'></div></td>");
else
filter.append("<td><div class='grid-cell'></div></td>");
}
}
}
}
hsb.append("</TR>");
}
filter.append("</tr>")
.append("</tbody></table>")
.append("</div>");
sb.append("<TABLE cellSpacing='0' atype='grid.lht' cellPadding='0' border='0' style='width:"+lockWidth+"px'><TBODY>")
.append("<TR class='grid-hl'>")
.append(th.toString())
.append("</TR>")
.append(hsb)
.append("</TBODY></TABLE>");
Integer height = (Integer)map.get(TABLE_HEIGHT);
sb.append("</DIV>");
if(hasFilter)
sb.append(filter);
int finnalRowHeght = (height.intValue()-rows.intValue()*((Integer)pro.get(ROW_HEIGHT)).intValue());
if((session.getTheme().toUpperCase().indexOf("HAP") != -1)&&hasFooterBar){
finnalRowHeght = finnalRowHeght - 1;
}
sb.append("<DIV class='grid-lb' atype='grid.lb' style='width:100%;height:"+finnalRowHeght+"px'>")
.append("</DIV></DIV>");
}
return sb.toString();
}
@SuppressWarnings("unchecked")
private String generateUnlockArea(Map map, List columns, Map pro,BuildSession session, String dataSet, CompositeMap model){
StringBuilder sb = new StringBuilder();
StringBuilder th = new StringBuilder();
StringBuilder filter = new StringBuilder("");
Integer rows = (Integer)pro.get(ROW_SPAN);
Iterator it = columns.iterator();
int unlockWidth = 0;
int row_height = ((Integer) pro.get(ROW_HEIGHT))==null?0:((Integer) pro.get(ROW_HEIGHT)).intValue();
while(it.hasNext()){
CompositeMap column = (CompositeMap)it.next();
GridColumnConfig gcc = GridColumnConfig.getInstance(column);
if(!gcc.isLock()){
List children = column.getChilds();
if(children == null){
boolean hidden = gcc.isHidden();
if(hidden)continue;
float cwidth = hidden?0:gcc.getWidth();
th.append("<th style='width:"+cwidth+"px;' dataindex='"+gcc.getName()+"'></th>");
unlockWidth +=cwidth;
}
}
}
pro.put(UNLOCK_WIDTH, new Integer(unlockWidth));
int finnalRowHeight = row_height;
sb.append("<table cellspacing='0' atype='grid.uht' cellpadding='0' border='0' style='width:"+unlockWidth+"px'><tbody>")
.append("<tr class='grid-hl'>")
.append(th.toString())
.append("<th width='34'> </th>")
.append("</tr>");
filter.append("<div class='grid-ufi' atype='grid.ufi' style='width:"+(pro.get(UNLOCK_WIDTH))+"px;");
filter.append("'>")
.append("<table cellspacing='0' atype='grid.ufit' cellpadding='0' border='0' style='width:"+unlockWidth+"px'><tbody>")
.append("<tr class='grid-hl'>")
.append(th.toString())
.append("<th width='34'> </th>")
.append("</tr>")
.append("<tr style=\"height:"+finnalRowHeight+"px;line-height:"+(row_height-6)+"px\">");
StringBuilder hsb = new StringBuilder();
for(int i=1,len = rows.intValue();i<=len;i++){
List list = (List)pro.get("l"+i);
hsb.append("<TR style=\"height:"+finnalRowHeight+"px;line-height:"+(row_height-6)+"px\">");
if(list!=null) {
Iterator lit = list.iterator();
while(lit.hasNext()){
CompositeMap column = (CompositeMap)lit.next();
GridColumnConfig gcc = GridColumnConfig.getInstance(column);
boolean hidden = gcc.isHidden();
if(hidden)continue;
String prompt = getFieldPrompt(session, column, dataSet);
String fullPrompt = getFieldFullPrompt(session, column, dataSet);
if("".equals(fullPrompt)){
fullPrompt = prompt;
}
String headTitle = session.getLocalizedPrompt(prompt);
if(headTitle!=null && headTitle.equals(prompt)){
headTitle = TextParser.parse(prompt, model);
}
hsb.append("<TD title='"+fullPrompt+"' class='grid-hc' atype='grid.head' style='height:"+finnalRowHeight+"px;visibility:"+(hidden?"hidden":"")+"' colspan='"+column.getInt(COL_SPAN,1)+"' rowspan='"+column.getInt(ROW_SPAN)+"' dataindex='"+gcc.getName()+"'><div");
if(gcc.getHeadStyle() != null){
hsb.append(" style='").append(gcc.getHeadStyle()).append("'");
}
hsb.append(">");
//必填
if(gcc.isRequired()){
hsb.append("<span class='prompt-required prompt-required-show' title='"+gcc.getName()+"'>*</span>");
}
hsb.append(headTitle);
if(gcc.isFilterable()){
hsb.append("<input class='grid-filter-icon' tabIndex='-1' disabled>");
}
if(gcc.isSortable()){
hsb.append("<span class='sort-btn'></span>");
}
hsb.append("</div></TD>");
if(i == len){
if(gcc.isFilterable())
filter.append("<td atype=\"grid-filter\" dataindex=\""+gcc.getName()+"\"><div class='grid-cell cell-editor'></div></td>");
else
filter.append("<td><div class='grid-cell'></div></td>");
}
}
}
hsb.append("</TR>");
}
filter.append("</tr>")
.append("</tbody></table>").append("</div>");
sb.append(hsb)
.append("</TBODY></TABLE>");
if(hasFilter)
map.put(UNLOCK_FILTER, filter.toString());
return sb.toString();
}
private String getFieldFullPrompt(BuildSession session, CompositeMap field, String dataset) {
String label = field.getString(GridColumnConfig.PROPERTITY_FULL_PROMPT, "");
if ("".equals(label)) {
String name = field.getString(ComponentConfig.PROPERTITY_NAME, "");
CompositeMap ds = getDataSet(session, dataset);
if (ds != null) {
CompositeMap fieldcm = ds.getChild(DataSetConfig.PROPERTITY_FIELDS);
if (fieldcm != null) {
List fields = fieldcm.getChilds();
Iterator it = fields.iterator();
while (it.hasNext()) {
CompositeMap fieldMap = (CompositeMap) it.next();
String fn = fieldMap.getString(ComponentConfig.PROPERTITY_NAME, "");
if (name.equals(fn)) {
label = fieldMap.getString(GridColumnConfig.PROPERTITY_FULL_PROMPT, "");
break;
}
}
}
}
}
return label;
}
}
...@@ -3,6 +3,7 @@ ...@@ -3,6 +3,7 @@
<bm:fields> <bm:fields>
<bm:field name="bp_code" displayWidth="200" forDisplay="true" forQuery="true" prompt="代理店编码"/> <bm:field name="bp_code" displayWidth="200" forDisplay="true" forQuery="true" prompt="代理店编码"/>
<bm:field name="value_name" displayWidth="200" forDisplay="true" forQuery="true" prompt="代理店名称"/> <bm:field name="value_name" displayWidth="200" forDisplay="true" forQuery="true" prompt="代理店名称"/>
<bm:field name="value_code"/>
</bm:fields> </bm:fields>
<bm:operations> <bm:operations>
......
...@@ -398,7 +398,8 @@ ...@@ -398,7 +398,8 @@
<bm:field name="business_type"/> <bm:field name="business_type"/>
</bm:fields> </bm:fields>
<bm:query-fields> <bm:query-fields>
<bm:query-field name="billing_object_name" queryExpression="vv.billing_object_name = ${@billing_object_name}"/> <bm:query-field name="billing_object_code" queryExpression="vv.billing_object_code = ${@billing_object_code}"/>
<!-- <bm:query-field name="billing_object_name" queryExpression="vv.billing_object_name = ${@billing_object_name}"/>-->
<bm:query-field name="cf_item" queryExpression="vv.cf_item = ${@cf_item}"/> <bm:query-field name="cf_item" queryExpression="vv.cf_item = ${@cf_item}"/>
<bm:query-field name="due_date_from" queryExpression="vv.due_date &gt;= to_date(${@due_date_from},&apos;yyyy-mm-dd&apos;)"/> <bm:query-field name="due_date_from" queryExpression="vv.due_date &gt;= to_date(${@due_date_from},&apos;yyyy-mm-dd&apos;)"/>
<bm:query-field name="due_date_to" queryExpression="vv.due_date &lt;= to_date(${@due_date_to},&apos;yyyy-mm-dd&apos;)"/> <bm:query-field name="due_date_to" queryExpression="vv.due_date &lt;= to_date(${@due_date_to},&apos;yyyy-mm-dd&apos;)"/>
...@@ -429,8 +430,8 @@ ...@@ -429,8 +430,8 @@
<bm:query-field name="document_type" queryExpression="vv.document_type=${@document_type}"/> <bm:query-field name="document_type" queryExpression="vv.document_type=${@document_type}"/>
<bm:query-field name="business_type" queryExpression="vv.business_type=${@business_type}"/> <bm:query-field name="business_type" queryExpression="vv.business_type=${@business_type}"/>
<bm:query-field name="contract_status" queryExpression="vv.contract_status = ${@contract_status}"/> <bm:query-field name="contract_status" queryExpression="vv.contract_status = ${@contract_status}"/>
<bm:query-field name="bp_id_agent_level1" queryExpression="vv.bp_id_agent_level1 = ${@bp_id_agent_level1}"/> <bm:query-field name="bp_id_agent_level1_n" queryExpression="vv.bp_id_agent_level1 = ${@bp_id_agent_level1}"/>
<bm:query-field name="bp_id_agent_level1_n" queryExpression="vv.bp_id_agent_level1_n like &apos;%&apos;||${@bp_id_agent_level1_n}||&apos;%&apos;"/> <!-- <bm:query-field name="bp_id_agent_level1_n" queryExpression="vv.bp_id_agent_level1_n like &apos;%&apos;||${@bp_id_agent_level1_n}||&apos;%&apos;"/>-->
<bm:query-field name="termination_date_from" queryExpression="to_date(t1.termination_date,&apos;yyyy-mm-dd&apos;) &gt;= to_date(${@termination_date_from},&apos;yyyy-mm-dd&apos;)"/> <bm:query-field name="termination_date_from" queryExpression="to_date(t1.termination_date,&apos;yyyy-mm-dd&apos;) &gt;= to_date(${@termination_date_from},&apos;yyyy-mm-dd&apos;)"/>
<bm:query-field name="termination_date_to" queryExpression="to_date(t1.termination_date,&apos;yyyy-mm-dd&apos;) &lt;= to_date(${@termination_date_to},&apos;yyyy-mm-dd&apos;)"/> <bm:query-field name="termination_date_to" queryExpression="to_date(t1.termination_date,&apos;yyyy-mm-dd&apos;) &lt;= to_date(${@termination_date_to},&apos;yyyy-mm-dd&apos;)"/>
<bm:query-field name="lease_channel" queryExpression="t1.lease_channel=${@lease_channel}"/> <bm:query-field name="lease_channel" queryExpression="t1.lease_channel=${@lease_channel}"/>
......
<?xml version="1.0" encoding="UTF-8"?>
<bm:model xmlns:bm="http://www.leaf-framework.org/schema/bm" needAccessControl="false">
<bm:operations>
<bm:operation name="query">
<bm:query-sql><![CDATA[
SELECT fam.table_name,
fam.table_pk_value,
fam.record_id,
faa.attachment_id,
faa.file_name,
faa.file_path
FROM prj_cdd_item_doc_ref doc,
fnd_atm_attachment_multi fam,
fnd_atm_attachment faa,
prj_cdd_item_check pck,
prj_cdd_item_list_grp_tab lgt,
prj_cdd_item_tab_group tg,
prj_cdd_item pci
WHERE doc.document_id = ${@table_pk_value}
AND doc.document_table = ${@table_name}
AND fam.table_name = 'PRJ_CDD_ITEM_CHECK'
AND fam.table_pk_value = TO_CHAR(doc.check_id)
AND fam.attachment_id = faa.attachment_id
and lgt.tab_group_id = tg.tab_group_id
and lgt.cdd_list_id = pci.cdd_list_id
and pci.cdd_item_id = lgt.cdd_item_id
and pci.cdd_list_id = ${@cdd_list_id}
AND lgt.cdd_list_id = pci.cdd_list_id
and pck.check_id=doc.check_id
and pci.cdd_item_id = pck.cdd_item_id
and tg.tab_group=${@group_code}
union all
SELECT fam.table_name,
fam.table_pk_value,
fam.record_id,
faa.attachment_id,
faa.file_name,
faa.file_path
FROM
fnd_atm_attachment_multi fam,
fnd_atm_attachment faa,
con_contract_content ccc
WHERE
fam.table_name = 'CON_CONTRACT'
AND fam.table_pk_value = ccc.check_id
AND fam.attachment_id = faa.attachment_id
and ccc.contract_id=${@table_pk_value}
and nvl(${@ele_flag},'N')='Y'
and ccc.check_id is not null
]]></bm:query-sql>
<bm:parameters>
<bm:parameter name="table_pk_value"/>
<bm:parameter name="table_name"/>
<bm:parameter name="cdd_list_id"/>
<bm:parameter name="group_code"/>
<bm:parameter name="@ele_flag"/>
</bm:parameters>
</bm:operation>
</bm:operations>
<bm:fields>
<bm:field name="table_name" databaseType="VARCHAR2" datatype="java.lang.String" physicalName="TABLE_NAME" required="true"/>
<bm:field name="table_pk_value" databaseType="VARCHAR2" datatype="java.lang.String" physicalName="TABLE_PK_VALUE" required="true"/>
<bm:field name="record_id" databaseType="NUMBER" datatype="java.lang.Long" physicalName="RECORD_ID" required="true"/>
<bm:field name="attachment_id" databaseType="NUMBER" datatype="java.lang.Long" physicalName="ATTACHMENT_ID" required="true"/>
<bm:field name="file_name" databaseType="VARCHAR2" datatype="java.lang.String" physicalName="FILE_NAME"/>
<bm:field name="file_path" databaseType="VARCHAR2" datatype="java.lang.String" physicalName="FILE_PATH"/>
</bm:fields>
</bm:model>
...@@ -104,18 +104,18 @@ function LoadFile() { ...@@ -104,18 +104,18 @@ function LoadFile() {
} }
function SaveFile(){ function SaveFile(){
try{ // try{
FileOutputStream fos=new FileOutputStream(new File("C:\\Users\\gaoyang\\Desktop\\",mFileName)); // FileOutputStream fos=new FileOutputStream(new File("C:\\Users\\gaoyang\\Desktop\\",mFileName));
fos.write(mFileBody,0,mFileSize); // fos.write(mFileBody,0,mFileSize);
fos.close(); // fos.close();
mResult=true; // mResult=true;
}catch(Exception e){ // }catch(Exception e){
mResult=false; // mResult=false;
} // }
finally{ // finally{
//
} // }
return (mResult); // return (mResult);
} }
function LoadBookMarks(){ function LoadBookMarks(){
......
...@@ -45,7 +45,11 @@ ...@@ -45,7 +45,11 @@
resp.setContentType("application/x-msdownload"); resp.setContentType("application/x-msdownload");
var zos = new ZipOutputStream(resp.getOutputStream()); var zos = new ZipOutputStream(resp.getOutputStream());
try { try {
var attachment_batch_dl = $bm('batch_download.lease_atm_batch_dl'); if ($ctx.parameter.group_flag=='Y'){
var attachment_batch_dl = $bm('batch_download.lease_atm_batch_dl_group');
}else{
var attachment_batch_dl = $bm('batch_download.lease_atm_batch_dl');
}
var result = attachment_batch_dl.queryAsMap(); var result = attachment_batch_dl.queryAsMap();
var arr = result.getChildren(); var arr = result.getChildren();
var file_exist_list = {}; var file_exist_list = {};
......
...@@ -34,12 +34,15 @@ ...@@ -34,12 +34,15 @@
<a:link id="${/parameter/@layout_code}_con_batch_dl_link_id" url="${/request/@context_path}/modules/cont/CON505/con_atm_batch_dl.lsc"/> <a:link id="${/parameter/@layout_code}_con_batch_dl_link_id" url="${/request/@context_path}/modules/cont/CON505/con_atm_batch_dl.lsc"/>
<a:link id="${/parameter/@layout_code}_con_cashflow_wirte_off_detail_link" url="${/request/@context_path}/modules/cont/CON302N/con_cashflow_wirte_off_detail.lview"/> <a:link id="${/parameter/@layout_code}_con_cashflow_wirte_off_detail_link" url="${/request/@context_path}/modules/cont/CON302N/con_cashflow_wirte_off_detail.lview"/>
<a:link id="con_approval_link_id" model="cont.CON505.contract_approval" modelaction="execute"/> <a:link id="con_approval_link_id" model="cont.CON505.contract_approval" modelaction="execute"/>
<link href="${/request/@context_path}/css/lightbox.css" rel="stylesheet" type="text/css"/> <!-- <link href="${/request/@context_path}/css/lightbox.css" rel="stylesheet" type="text/css"/>-->
<script src="${/request/@context_path}/javascripts/lightbox.js" type="text/javascript"/> <!-- <script src="${/request/@context_path}/javascripts/lightbox.js" type="text/javascript"/>-->
<a:link id="${/parameter/@layout_code}${/parameter/@tree_code}_hls_fin_calculator_update_link_id" <a:link id="${/parameter/@layout_code}${/parameter/@tree_code}_hls_fin_calculator_update_link_id"
url="${/request/@context_path}/modules/hls/HLS500N/hls_fin_calculator_update_n.lview"/> url="${/request/@context_path}/modules/hls/HLS500N/hls_fin_calculator_update_n.lview"/>
<a:link id="get_atch_download_link" url="${/request/@context_path}/modules/batch_download/lease_atm_batch_dl.lsc"/>
<link href="${/request/@context_path}/modules/viewerjs/viewer.css" rel="stylesheet"/>
<script src="${/request/@context_path}/modules/viewerjs/viewer.js"/>
<script src="${/request/@context_path}/modules/viewerjs/viewer_tool.js"/>
<script type="text/javascript"><![CDATA[ <script type="text/javascript"><![CDATA[
Ext.ux.Lightbox.register('a[ref=img]', true);
function lock_current_window() { function lock_current_window() {
Leaf.Masker.mask(Ext.getBody(), '${l:HLS.EXECUTING}'); Leaf.Masker.mask(Ext.getBody(), '${l:HLS.EXECUTING}');
} }
...@@ -163,9 +166,15 @@ ...@@ -163,9 +166,15 @@
// if (file_name.indexOf('.PDF') >= 0) { // if (file_name.indexOf('.PDF') >= 0) {
// url = url + '<a href=javascript:view_pdf(\'' + temp[1] + '\')>' + temp[0] + '</a>' + ','; // url = url + '<a href=javascript:view_pdf(\'' + temp[1] + '\')>' + temp[0] + '</a>' + ',';
// } else // } else
// if (file_suffix == 'BMP' || file_suffix == 'JPG' || file_suffix == 'JPEG' || file_suffix == 'PNG' || file_suffix == 'GIF') {
// url = url + '<a href=' + link + temp[1] + ' ref="img">' + temp[0] + '</a>' + ',';
// }
if (file_suffix == 'BMP' || file_suffix == 'JPG' || file_suffix == 'JPEG' || file_suffix == 'PNG' || file_suffix == 'GIF') { if (file_suffix == 'BMP' || file_suffix == 'JPG' || file_suffix == 'JPEG' || file_suffix == 'PNG' || file_suffix == 'GIF') {
url = url + '<a href=' + link + temp[1] + ' ref="img">' + temp[0] + '</a>' + ','; // url = url + '<a ref="img" href=' + link + temp[1] + '>' + temp[0] + '</a>' + ',';
} else { link_function = 'show_viewer_more';
url = url + '<a href="javascript:window[\'' + link_function + '\'](\'' + link + '\',\'' + temp[1] + '\',\'' + temp[0] + '\',\'' + value + '\');">' + temp[0] + '</a>' + ',';
}
else {
url = url + '<a href=' + link + temp[1] + '>' + temp[0] + '</a>' + ','; url = url + '<a href=' + link + temp[1] + '>' + temp[0] + '</a>' + ',';
} }
} }
...@@ -597,6 +606,40 @@ ...@@ -597,6 +606,40 @@
$(ds_id).setQueryParameter('contract_id','${/parameter/@contract_id}'); $(ds_id).setQueryParameter('contract_id','${/parameter/@contract_id}');
$(ds_id).query(); $(ds_id).query();
}) })
//附件打包下载
window['${/parameter/@layout_code}_C_ATTCH_I_USER_BUTTON1_layout_dynamic_tab_click'] = function () {
var con_ds_id = get_dsid_by_basetable(window['${/parameter/@layout_code}_layoutDataSetList'], 'con_contract');
var contract_record = $(con_ds_id).getAt(0);
var contract_id = contract_record.get('contract_id');
var contract_number = contract_record.get('contract_number');
var cdd_list_id=contract_record.get('cdd_list_id');
var doc_code=contract_number+'-'+'SIGN';
var url_l = $('get_atch_download_link').getUrl() + '?table_pk_value=' + contract_id + '&table_name=CON_CONTRACT'+ '&doc_code=' + doc_code+ '&group_flag=Y'+ '&cdd_list_id=' + cdd_list_id+ '&group_code=SIGN'+'&ele_flag=Y';
window.open(href = url_l, target = "_self");
};
//附件打包下载
window['${/parameter/@layout_code}_C_ATTCH_2_USER_BUTTON1_layout_dynamic_tab_click'] = function () {
var con_ds_id = get_dsid_by_basetable(window['${/parameter/@layout_code}_layoutDataSetList'], 'con_contract');
var contract_record = $(con_ds_id).getAt(0);
var contract_id = contract_record.get('contract_id');
var contract_number = contract_record.get('contract_number');
var cdd_list_id=contract_record.get('cdd_list_id');
var doc_code=contract_number+'-'+'SIGN';
var url_l = $('get_atch_download_link').getUrl() + '?table_pk_value=' + contract_id + '&table_name=CON_CONTRACT'+ '&doc_code=' + doc_code+ '&group_flag=Y'+ '&cdd_list_id=' + cdd_list_id+ '&group_code=LEASE_ANNEX';
window.open(href = url_l, target = "_self");
};
//附件打包下载
window['${/parameter/@layout_code}_C_ATTCH_1_USER_BUTTON1_layout_dynamic_tab_click'] = function () {
var con_ds_id = get_dsid_by_basetable(window['${/parameter/@layout_code}_layoutDataSetList'], 'con_contract');
var contract_record = $(con_ds_id).getAt(0);
var contract_id = contract_record.get('contract_id');
var contract_number = contract_record.get('contract_number');
var cdd_list_id=contract_record.get('cdd_list_id');
var doc_code=contract_number+'-'+'PRJ';
var url_l = $('get_atch_download_link').getUrl() + '?table_pk_value=' + contract_id + '&table_name=CON_CONTRACT'+ '&doc_code=' + doc_code+ '&group_flag=Y'+ '&cdd_list_id=' + cdd_list_id+ '&group_code=CREDIT_CHECK';
window.open(href = url_l, target = "_self");
};
]]></script> ]]></script>
<a:screen-include screen="modules/cont/CON500/con_contract_get_layout_code.lview"/> <a:screen-include screen="modules/cont/CON500/con_contract_get_layout_code.lview"/>
......
This source diff could not be displayed because it is too large. You can view the blob instead.
...@@ -57,11 +57,13 @@ ...@@ -57,11 +57,13 @@
<a:link id="prj_approval_link_id" model="prj.PRJ501N.project_approval" modelaction="update"/> <a:link id="prj_approval_link_id" model="prj.PRJ501N.project_approval" modelaction="update"/>
<a:link id="check_prj_lease_item_link_id" model="prj.PRJ501N.project_approval" modelaction="execute"/> <a:link id="check_prj_lease_item_link_id" model="prj.PRJ501N.project_approval" modelaction="execute"/>
<script src="${/request/@context_path}/javascripts/jquery-1.6.4.min.js" type="text/javascript"/> <script src="${/request/@context_path}/javascripts/jquery-1.6.4.min.js" type="text/javascript"/>
<!--<link href="${/request/@context_path}/css/lightbox.css" rel="stylesheet" type="text/css"/> <!--<link href="${/request/@context_path}/css/lightbox.css" rel="stylesheet" type="text/css"/>
<script src="${/request/@context_path}/javascripts/lightbox.js" type="text/javascript"/>--> <script src="${/request/@context_path}/javascripts/lightbox.js" type="text/javascript"/>-->
<a:link id="prj_check_prj_record_link_n" model="hls.HLS500N.check_prj_record" modelaction="execute"/> <a:link id="prj_check_prj_record_link_n" model="hls.HLS500N.check_prj_record" modelaction="execute"/>
<a:link id="get_atch_download_link" url="${/request/@context_path}/modules/batch_download/lease_atm_batch_dl.lsc"/>
<link href="${/request/@context_path}/modules/viewerjs/viewer.css" rel="stylesheet"/>
<script src="${/request/@context_path}/modules/viewerjs/viewer.js"/>
<script src="${/request/@context_path}/modules/viewerjs/viewer_tool.js"/>
<script type="text/javascript"><![CDATA[ <script type="text/javascript"><![CDATA[
jQuery.noConflict(); jQuery.noConflict();
window['${/parameter/@layout_code}_user_button5_layout_dynamic_click'] = function () { window['${/parameter/@layout_code}_user_button5_layout_dynamic_click'] = function () {
...@@ -468,9 +470,15 @@ ...@@ -468,9 +470,15 @@
var file_name = temp[0].toUpperCase(); var file_name = temp[0].toUpperCase();
var file_suffix = temp[0].substr(temp[0].lastIndexOf('.') + 1).toUpperCase(); var file_suffix = temp[0].substr(temp[0].lastIndexOf('.') + 1).toUpperCase();
if (file_name.indexOf('.BMP') >= 0 || file_name.indexOf('.JPG') >= 0 || file_name.indexOf('.JPEG') >= 0 || file_name.indexOf('.PNG') >= 0 || file_name.indexOf('.GIF') >= 0) { // if (file_name.indexOf('.BMP') >= 0 || file_name.indexOf('.JPG') >= 0 || file_name.indexOf('.JPEG') >= 0 || file_name.indexOf('.PNG') >= 0 || file_name.indexOf('.GIF') >= 0) {
url = url + '<a href=' + link + temp[1] + ' ref="img">' + temp[0] + '</a>' + ','; // url = url + '<a href=' + link + temp[1] + ' ref="img">' + temp[0] + '</a>' + ',';
} else { // }
if (file_suffix == 'BMP' || file_suffix == 'JPG' || file_suffix == 'JPEG' || file_suffix == 'PNG' || file_suffix == 'GIF') {
// url = url + '<a ref="img" href=' + link + temp[1] + '>' + temp[0] + '</a>' + ',';
link_function = 'show_viewer_more';
url = url + '<a href="javascript:window[\'' + link_function + '\'](\'' + link + '\',\'' + temp[1] + '\',\'' + temp[0] + '\',\'' + value + '\');">' + temp[0] + '</a>' + ',';
}
else {
url = url + '<a href=' + link + temp[1] + '>' + temp[0] + '</a>' + ','; url = url + '<a href=' + link + temp[1] + '>' + temp[0] + '</a>' + ',';
} }
} }
...@@ -1162,7 +1170,15 @@ ...@@ -1162,7 +1170,15 @@
return true; return true;
}; };
//附件打包下载
window['${/parameter/@layout_code}_ACY_USER_BUTTON1_layout_dynamic_tab_click'] = function () {
var prj_project_ds_id = get_dsid_by_basetable(window['${/parameter/@layout_code}_layoutDataSetList'], 'prj_project');
var prj_project_record = $(prj_project_ds_id).getAt(0);
var project_id = prj_project_record.get('project_id');
var project_number = prj_project_record.get('project_number');
var url_l = $('get_atch_download_link').getUrl() + '?table_pk_value=' + project_id + '&table_name=PRJ_PROJECT'+ '&doc_code=' + project_number;
window.open(href = url_l, target = "_self");
};
]]></script> ]]></script>
<a:screen-include screen="modules/cont/CON500/con_contract_get_layout_code.lview"/> <a:screen-include screen="modules/cont/CON500/con_contract_get_layout_code.lview"/>
......
...@@ -58,6 +58,10 @@ ...@@ -58,6 +58,10 @@
<!--<link href="${/request/@context_path}/css/lightbox.css" rel="stylesheet" type="text/css"/> <!--<link href="${/request/@context_path}/css/lightbox.css" rel="stylesheet" type="text/css"/>
<script src="${/request/@context_path}/javascripts/lightbox.js" type="text/javascript"/>--> <script src="${/request/@context_path}/javascripts/lightbox.js" type="text/javascript"/>-->
<a:link id="get_atch_download_link" url="${/request/@context_path}/modules/batch_download/lease_atm_batch_dl.lsc"/>
<link href="${/request/@context_path}/modules/viewerjs/viewer.css" rel="stylesheet"/>
<script src="${/request/@context_path}/modules/viewerjs/viewer.js"/>
<script src="${/request/@context_path}/modules/viewerjs/viewer_tool.js"/>
<script type="text/javascript"><![CDATA[ <script type="text/javascript"><![CDATA[
window['${/parameter/@layout_code}_user_button5_layout_dynamic_click'] = function () { window['${/parameter/@layout_code}_user_button5_layout_dynamic_click'] = function () {
Leaf.showConfirm('提示', '是否确认生成合同?', function () { Leaf.showConfirm('提示', '是否确认生成合同?', function () {
...@@ -438,9 +442,15 @@ ...@@ -438,9 +442,15 @@
var file_name = temp[0].toUpperCase(); var file_name = temp[0].toUpperCase();
var file_suffix = temp[0].substr(temp[0].lastIndexOf('.') + 1).toUpperCase(); var file_suffix = temp[0].substr(temp[0].lastIndexOf('.') + 1).toUpperCase();
if (file_name.indexOf('.BMP') >= 0 || file_name.indexOf('.JPG') >= 0 || file_name.indexOf('.JPEG') >= 0 || file_name.indexOf('.PNG') >= 0 || file_name.indexOf('.GIF') >= 0) { // if (file_name.indexOf('.BMP') >= 0 || file_name.indexOf('.JPG') >= 0 || file_name.indexOf('.JPEG') >= 0 || file_name.indexOf('.PNG') >= 0 || file_name.indexOf('.GIF') >= 0) {
url = url + '<a href=' + link + temp[1] + ' ref="img">' + temp[0] + '</a>' + ','; // url = url + '<a href=' + link + temp[1] + ' ref="img">' + temp[0] + '</a>' + ',';
} else { // }
if (file_suffix == 'BMP' || file_suffix == 'JPG' || file_suffix == 'JPEG' || file_suffix == 'PNG' || file_suffix == 'GIF') {
// url = url + '<a ref="img" href=' + link + temp[1] + '>' + temp[0] + '</a>' + ',';
link_function = 'show_viewer_more';
url = url + '<a href="javascript:window[\'' + link_function + '\'](\'' + link + '\',\'' + temp[1] + '\',\'' + temp[0] + '\',\'' + value + '\');">' + temp[0] + '</a>' + ',';
}
else {
url = url + '<a href=' + link + temp[1] + '>' + temp[0] + '</a>' + ','; url = url + '<a href=' + link + temp[1] + '>' + temp[0] + '</a>' + ',';
} }
} }
...@@ -935,7 +945,15 @@ ...@@ -935,7 +945,15 @@
} }
} }
}; };
//附件打包下载
window['${/parameter/@layout_code}_ACY_USER_BUTTON1_layout_dynamic_tab_click'] = function () {
var prj_project_ds_id = get_dsid_by_basetable(window['${/parameter/@layout_code}_layoutDataSetList'], 'prj_project');
var prj_project_record = $(prj_project_ds_id).getAt(0);
var project_id = prj_project_record.get('project_id');
var project_number = prj_project_record.get('project_number');
var url_l = $('get_atch_download_link').getUrl() + '?table_pk_value=' + project_id + '&table_name=PRJ_PROJECT'+ '&doc_code=' + project_number;
window.open(href = url_l, target = "_self");
};
]]></script> ]]></script>
<a:screen-include screen="modules/cont/CON500/con_contract_get_layout_code.lview"/> <a:screen-include screen="modules/cont/CON500/con_contract_get_layout_code.lview"/>
......
/*!
* Viewer.js v1.3.0
* https://fengyuanchen.github.io/viewerjs
*
* Copyright 2015-present Chen Fengyuan
* Released under the MIT license
*
* Date: 2018-10-25T12:41:54.899Z
*/
'use strict';
function _typeof(obj) {
if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") {
_typeof = function (obj) {
return typeof obj;
};
} else {
_typeof = function (obj) {
return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj;
};
}
return _typeof(obj);
}
function _classCallCheck(instance, Constructor) {
if (!(instance instanceof Constructor)) {
throw new TypeError("Cannot call a class as a function");
}
}
function _defineProperties(target, props) {
for (var i = 0; i < props.length; i++) {
var descriptor = props[i];
descriptor.enumerable = descriptor.enumerable || false;
descriptor.configurable = true;
if ("value" in descriptor) descriptor.writable = true;
Object.defineProperty(target, descriptor.key, descriptor);
}
}
function _createClass(Constructor, protoProps, staticProps) {
if (protoProps) _defineProperties(Constructor.prototype, protoProps);
if (staticProps) _defineProperties(Constructor, staticProps);
return Constructor;
}
var DEFAULTS = {
/**
* Enable a modal backdrop, specify `static` for a backdrop
* which doesn't close the modal on click.
* @type {boolean}
*/
backdrop: true,
/**
* Show the button on the top-right of the viewer.
* @type {boolean}
*/
button: true,
/**
* Show the navbar.
* @type {boolean | number}
*/
navbar: true,
/**
* Specify the visibility and the content of the title.
* @type {boolean | number | Function | Array}
*/
title: true,
/**
* Show the toolbar.
* @type {boolean | number | Object}
*/
toolbar: true,
/**
* Custom class name(s) to add to the viewer's root element.
* @type {string}
*/
className: '',
/**
* Define where to put the viewer in modal mode.
* @type {string | Element}
*/
container: 'body',
/**
* Filter the images for viewing. Return true if the image is viewable.
* @type {Function}
*/
filter: null,
/**
* Enable to request fullscreen when play.
* @type {boolean}
*/
fullscreen: true,
/**
* Define the initial index of image for viewing.
* @type {number}
*/
initialViewIndex: 0,
/**
* Enable inline mode.
* @type {boolean}
*/
inline: false,
/**
* The amount of time to delay between automatically cycling an image when playing.
* @type {number}
*/
interval: 5000,
/**
* Enable keyboard support.
* @type {boolean}
*/
keyboard: true,
/**
* Indicate if show a loading spinner when load image or not.
* @type {boolean}
*/
loading: true,
/**
* Indicate if enable loop viewing or not.
* @type {boolean}
*/
loop: true,
/**
* Min width of the viewer in inline mode.
* @type {number}
*/
minWidth: 200,
/**
* Min height of the viewer in inline mode.
* @type {number}
*/
minHeight: 100,
/**
* Enable to move the image.
* @type {boolean}
*/
movable: true,
/**
* Enable to zoom the image.
* @type {boolean}
*/
zoomable: true,
/**
* Enable to rotate the image.
* @type {boolean}
*/
rotatable: true,
/**
* Enable to scale the image.
* @type {boolean}
*/
scalable: true,
/**
* Indicate if toggle the image size between its natural size
* and initial size when double click on the image or not.
* @type {boolean}
*/
toggleOnDblclick: true,
/**
* Show the tooltip with image ratio (percentage) when zoom in or zoom out.
* @type {boolean}
*/
tooltip: true,
/**
* Enable CSS3 Transition for some special elements.
* @type {boolean}
*/
transition: true,
/**
* Define the CSS `z-index` value of viewer in modal mode.
* @type {number}
*/
zIndex: 2015,
/**
* Define the CSS `z-index` value of viewer in inline mode.
* @type {number}
*/
zIndexInline: 0,
/**
* Define the ratio when zoom the image by wheeling mouse.
* @type {number}
*/
zoomRatio: 0.1,
/**
* Define the min ratio of the image when zoom out.
* @type {number}
*/
minZoomRatio: 0.01,
/**
* Define the max ratio of the image when zoom in.
* @type {number}
*/
maxZoomRatio: 100,
/**
* Define where to get the original image URL for viewing.
* @type {string | Function}
*/
url: 'src',
/**
* Event shortcuts.
* @type {Function}
*/
ready: null,
show: null,
shown: null,
hide: null,
hidden: null,
view: null,
viewed: null,
zoom: null,
zoomed: null
};
var TEMPLATE = '<div class="viewer-container" touch-action="none">' + '<div class="viewer-canvas"></div>' + '<div class="viewer-footer">' + '<div class="viewer-title"></div>' + '<div class="viewer-toolbar"></div>' + '<div class="viewer-navbar">' + '<ul class="viewer-list"></ul>' + '</div>' + '</div>' + '<div class="viewer-tooltip"></div>' + '<div role="button" class="viewer-button" data-viewer-action="mix"></div>' + '<div class="viewer-player"></div>' + '</div>';
var IN_BROWSER = typeof window !== 'undefined';
var WINDOW = IN_BROWSER ? window : {};
var NAMESPACE = 'viewer'; // Actions
var ACTION_MOVE = 'move';
var ACTION_SWITCH = 'switch';
var ACTION_ZOOM = 'zoom'; // Classes
var CLASS_ACTIVE = "".concat(NAMESPACE, "-active");
var CLASS_CLOSE = "".concat(NAMESPACE, "-close");
var CLASS_FADE = "".concat(NAMESPACE, "-fade");
var CLASS_FIXED = "".concat(NAMESPACE, "-fixed");
var CLASS_FULLSCREEN = "".concat(NAMESPACE, "-fullscreen");
var CLASS_FULLSCREEN_EXIT = "".concat(NAMESPACE, "-fullscreen-exit");
var CLASS_HIDE = "".concat(NAMESPACE, "-hide");
var CLASS_HIDE_MD_DOWN = "".concat(NAMESPACE, "-hide-md-down");
var CLASS_HIDE_SM_DOWN = "".concat(NAMESPACE, "-hide-sm-down");
var CLASS_HIDE_XS_DOWN = "".concat(NAMESPACE, "-hide-xs-down");
var CLASS_IN = "".concat(NAMESPACE, "-in");
var CLASS_INVISIBLE = "".concat(NAMESPACE, "-invisible");
var CLASS_LOADING = "".concat(NAMESPACE, "-loading");
var CLASS_MOVE = "".concat(NAMESPACE, "-move");
var CLASS_OPEN = "".concat(NAMESPACE, "-open");
var CLASS_SHOW = "".concat(NAMESPACE, "-show");
var CLASS_TRANSITION = "".concat(NAMESPACE, "-transition"); // Events
var EVENT_CLICK = 'click';
var EVENT_DBLCLICK = 'dblclick';
var EVENT_DRAG_START = 'dragstart';
var EVENT_HIDDEN = 'hidden';
var EVENT_HIDE = 'hide';
var EVENT_KEY_DOWN = 'keydown';
var EVENT_LOAD = 'load';
var EVENT_POINTER_DOWN = WINDOW.PointerEvent ? 'pointerdown' : 'touchstart mousedown';
var EVENT_POINTER_MOVE = WINDOW.PointerEvent ? 'pointermove' : 'touchmove mousemove';
var EVENT_POINTER_UP = WINDOW.PointerEvent ? 'pointerup pointercancel' : 'touchend touchcancel mouseup';
var EVENT_READY = 'ready';
var EVENT_RESIZE = 'resize';
var EVENT_SHOW = 'show';
var EVENT_SHOWN = 'shown';
var EVENT_TRANSITION_END = 'transitionend';
var EVENT_VIEW = 'view';
var EVENT_VIEWED = 'viewed';
var EVENT_WHEEL = 'wheel mousewheel DOMMouseScroll';
var EVENT_ZOOM = 'zoom';
var EVENT_ZOOMED = 'zoomed'; // Data keys
var DATA_ACTION = "".concat(NAMESPACE, "Action");
var BUTTONS = ['zoom-in', 'zoom-out', 'one-to-one', 'reset', 'prev', 'play', 'next', 'rotate-left', 'rotate-right', 'flip-horizontal', 'flip-vertical']; // RegExps
var REGEXP_SPACES = /\s\s*/;
/**
* Check if the given value is a string.
* @param {*} value - The value to check.
* @returns {boolean} Returns `true` if the given value is a string, else `false`.
*/
function isString(value) {
return typeof value === 'string';
}
/**
* Check if the given value is not a number.
*/
var isNaN = Number.isNaN || WINDOW.isNaN;
/**
* Check if the given value is a number.
* @param {*} value - The value to check.
* @returns {boolean} Returns `true` if the given value is a number, else `false`.
*/
function isNumber(value) {
return typeof value === 'number' && !isNaN(value);
}
/**
* Check if the given value is undefined.
* @param {*} value - The value to check.
* @returns {boolean} Returns `true` if the given value is undefined, else `false`.
*/
function isUndefined(value) {
return typeof value === 'undefined';
}
/**
* Check if the given value is an object.
* @param {*} value - The value to check.
* @returns {boolean} Returns `true` if the given value is an object, else `false`.
*/
function isObject(value) {
return _typeof(value) === 'object' && value !== null;
}
var hasOwnProperty = Object.prototype.hasOwnProperty;
/**
* Check if the given value is a plain object.
* @param {*} value - The value to check.
* @returns {boolean} Returns `true` if the given value is a plain object, else `false`.
*/
function isPlainObject(value) {
if (!isObject(value)) {
return false;
}
try {
var _constructor = value.constructor;
var prototype = _constructor.prototype;
return _constructor && prototype && hasOwnProperty.call(prototype, 'isPrototypeOf');
} catch (e) {
return false;
}
}
/**
* Check if the given value is a function.
* @param {*} value - The value to check.
* @returns {boolean} Returns `true` if the given value is a function, else `false`.
*/
function isFunction(value) {
return typeof value === 'function';
}
/**
* Iterate the given data.
* @param {*} data - The data to iterate.
* @param {Function} callback - The process function for each element.
* @returns {*} The original data.
*/
function forEach(data, callback) {
if (data && isFunction(callback)) {
if (Array.isArray(data) || isNumber(data.length)
/* array-like */
) {
var length = data.length;
var i;
for (i = 0; i < length; i += 1) {
if (callback.call(data, data[i], i, data) === false) {
break;
}
}
} else if (isObject(data)) {
Object.keys(data).forEach(function (key) {
callback.call(data, data[key], key, data);
});
}
}
return data;
}
/**
* Extend the given object.
* @param {*} obj - The object to be extended.
* @param {*} args - The rest objects which will be merged to the first object.
* @returns {Object} The extended object.
*/
var assign = Object.assign || function assign(obj) {
for (var _len = arguments.length, args = new Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {
args[_key - 1] = arguments[_key];
}
if (isObject(obj) && args.length > 0) {
args.forEach(function (arg) {
if (isObject(arg)) {
Object.keys(arg).forEach(function (key) {
obj[key] = arg[key];
});
}
});
}
return obj;
};
var REGEXP_SUFFIX = /^(?:width|height|left|top|marginLeft|marginTop)$/;
/**
* Apply styles to the given element.
* @param {Element} element - The target element.
* @param {Object} styles - The styles for applying.
*/
function setStyle(element, styles) {
var style = element.style;
forEach(styles, function (value, property) {
if (REGEXP_SUFFIX.test(property) && isNumber(value)) {
value += 'px';
}
style[property] = value;
});
}
/**
* Check if the given element has a special class.
* @param {Element} element - The element to check.
* @param {string} value - The class to search.
* @returns {boolean} Returns `true` if the special class was found.
*/
function hasClass(element, value) {
return element.classList ? element.classList.contains(value) : element.className.indexOf(value) > -1;
}
/**
* Add classes to the given element.
* @param {Element} element - The target element.
* @param {string} value - The classes to be added.
*/
function addClass(element, value) {
if (!value) {
return;
}
if (isNumber(element.length)) {
forEach(element, function (elem) {
addClass(elem, value);
});
return;
}
if (element.classList) {
element.classList.add(value);
return;
}
var className = element.className.trim();
if (!className) {
element.className = value;
} else if (className.indexOf(value) < 0) {
element.className = "".concat(className, " ").concat(value);
}
}
/**
* Remove classes from the given element.
* @param {Element} element - The target element.
* @param {string} value - The classes to be removed.
*/
function removeClass(element, value) {
if (!value) {
return;
}
if (isNumber(element.length)) {
forEach(element, function (elem) {
removeClass(elem, value);
});
return;
}
if (element.classList) {
element.classList.remove(value);
return;
}
if (element.className.indexOf(value) >= 0) {
element.className = element.className.replace(value, '');
}
}
/**
* Add or remove classes from the given element.
* @param {Element} element - The target element.
* @param {string} value - The classes to be toggled.
* @param {boolean} added - Add only.
*/
function toggleClass(element, value, added) {
if (!value) {
return;
}
if (isNumber(element.length)) {
forEach(element, function (elem) {
toggleClass(elem, value, added);
});
return;
} // IE10-11 doesn't support the second parameter of `classList.toggle`
if (added) {
addClass(element, value);
} else {
removeClass(element, value);
}
}
var REGEXP_HYPHENATE = /([a-z\d])([A-Z])/g;
/**
* Transform the given string from camelCase to kebab-case
* @param {string} value - The value to transform.
* @returns {string} The transformed value.
*/
function hyphenate(value) {
return value.replace(REGEXP_HYPHENATE, '$1-$2').toLowerCase();
}
/**
* Get data from the given element.
* @param {Element} element - The target element.
* @param {string} name - The data key to get.
* @returns {string} The data value.
*/
function getData(element, name) {
if (isObject(element[name])) {
return element[name];
}
if (element.dataset) {
return element.dataset[name];
}
return element.getAttribute("data-".concat(hyphenate(name)));
}
/**
* Set data to the given element.
* @param {Element} element - The target element.
* @param {string} name - The data key to set.
* @param {string} data - The data value.
*/
function setData(element, name, data) {
if (isObject(data)) {
element[name] = data;
} else if (element.dataset) {
element.dataset[name] = data;
} else {
element.setAttribute("data-".concat(hyphenate(name)), data);
}
}
var onceSupported = function () {
var supported = false;
if (IN_BROWSER) {
var once = false;
var listener = function listener() {};
var options = Object.defineProperty({}, 'once', {
get: function get() {
supported = true;
return once;
},
/**
* This setter can fix a `TypeError` in strict mode
* {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Errors/Getter_only}
* @param {boolean} value - The value to set
*/
set: function set(value) {
once = value;
}
});
WINDOW.addEventListener('test', listener, options);
WINDOW.removeEventListener('test', listener, options);
}
return supported;
}();
/**
* Remove event listener from the target element.
* @param {Element} element - The event target.
* @param {string} type - The event type(s).
* @param {Function} listener - The event listener.
* @param {Object} options - The event options.
*/
function removeListener(element, type, listener) {
var options = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : {};
var handler = listener;
type.trim().split(REGEXP_SPACES).forEach(function (event) {
if (!onceSupported) {
var listeners = element.listeners;
if (listeners && listeners[event] && listeners[event][listener]) {
handler = listeners[event][listener];
delete listeners[event][listener];
if (Object.keys(listeners[event]).length === 0) {
delete listeners[event];
}
if (Object.keys(listeners).length === 0) {
delete element.listeners;
}
}
}
element.removeEventListener(event, handler, options);
});
}
/**
* Add event listener to the target element.
* @param {Element} element - The event target.
* @param {string} type - The event type(s).
* @param {Function} listener - The event listener.
* @param {Object} options - The event options.
*/
function addListener(element, type, listener) {
var options = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : {};
var _handler = listener;
type.trim().split(REGEXP_SPACES).forEach(function (event) {
if (options.once && !onceSupported) {
var _element$listeners = element.listeners,
listeners = _element$listeners === void 0 ? {} : _element$listeners;
_handler = function handler() {
delete listeners[event][listener];
element.removeEventListener(event, _handler, options);
for (var _len2 = arguments.length, args = new Array(_len2), _key2 = 0; _key2 < _len2; _key2++) {
args[_key2] = arguments[_key2];
}
listener.apply(element, args);
};
if (!listeners[event]) {
listeners[event] = {};
}
if (listeners[event][listener]) {
element.removeEventListener(event, listeners[event][listener], options);
}
listeners[event][listener] = _handler;
element.listeners = listeners;
}
element.addEventListener(event, _handler, options);
});
}
/**
* Dispatch event on the target element.
* @param {Element} element - The event target.
* @param {string} type - The event type(s).
* @param {Object} data - The additional event data.
* @returns {boolean} Indicate if the event is default prevented or not.
*/
function dispatchEvent(element, type, data) {
var event; // Event and CustomEvent on IE9-11 are global objects, not constructors
if (isFunction(Event) && isFunction(CustomEvent)) {
event = new CustomEvent(type, {
detail: data,
bubbles: true,
cancelable: true
});
} else {
event = document.createEvent('CustomEvent');
event.initCustomEvent(type, true, true, data);
}
return element.dispatchEvent(event);
}
/**
* Get the offset base on the document.
* @param {Element} element - The target element.
* @returns {Object} The offset data.
*/
function getOffset(element) {
var box = element.getBoundingClientRect();
return {
left: box.left + (window.pageXOffset - document.documentElement.clientLeft),
top: box.top + (window.pageYOffset - document.documentElement.clientTop)
};
}
/**
* Get transforms base on the given object.
* @param {Object} obj - The target object.
* @returns {string} A string contains transform values.
*/
function getTransforms(_ref) {
var rotate = _ref.rotate,
scaleX = _ref.scaleX,
scaleY = _ref.scaleY,
translateX = _ref.translateX,
translateY = _ref.translateY;
var values = [];
if (isNumber(translateX) && translateX !== 0) {
values.push("translateX(".concat(translateX, "px)"));
}
if (isNumber(translateY) && translateY !== 0) {
values.push("translateY(".concat(translateY, "px)"));
} // Rotate should come first before scale to match orientation transform
if (isNumber(rotate) && rotate !== 0) {
values.push("rotate(".concat(rotate, "deg)"));
}
if (isNumber(scaleX) && scaleX !== 1) {
values.push("scaleX(".concat(scaleX, ")"));
}
if (isNumber(scaleY) && scaleY !== 1) {
values.push("scaleY(".concat(scaleY, ")"));
}
var transform = values.length ? values.join(' ') : 'none';
return {
WebkitTransform: transform,
msTransform: transform,
transform: transform
};
}
/**
* Get an image name from an image url.
* @param {string} url - The target url.
* @example
* // picture.jpg
* getImageNameFromURL('http://domain.com/path/to/picture.jpg?size=1280×960')
* @returns {string} A string contains the image name.
*/
function getImageNameFromURL(url) {
return isString(url) ? url.replace(/^.*\//, '').replace(/[?&#].*$/, '') : '';
}
var IS_SAFARI = WINDOW.navigator && /(Macintosh|iPhone|iPod|iPad).*AppleWebKit/i.test(WINDOW.navigator.userAgent);
/**
* Get an image's natural sizes.
* @param {string} image - The target image.
* @param {Function} callback - The callback function.
* @returns {HTMLImageElement} The new image.
*/
function getImageNaturalSizes(image, callback) {
var newImage = document.createElement('img'); // Modern browsers (except Safari)
if (image.naturalWidth && !IS_SAFARI) {
callback(image.naturalWidth, image.naturalHeight);
return newImage;
}
var body = document.body || document.documentElement;
newImage.onload = function () {
callback(newImage.width, newImage.height);
if (!IS_SAFARI) {
body.removeChild(newImage);
}
};
newImage.src = image.src; // iOS Safari will convert the image automatically
// with its orientation once append it into DOM
if (!IS_SAFARI) {
newImage.style.cssText = 'left:0;' + 'max-height:none!important;' + 'max-width:none!important;' + 'min-height:0!important;' + 'min-width:0!important;' + 'opacity:0;' + 'position:absolute;' + 'top:0;' + 'z-index:-1;';
body.appendChild(newImage);
}
return newImage;
}
/**
* Get the related class name of a responsive type number.
* @param {string} type - The responsive type.
* @returns {string} The related class name.
*/
function getResponsiveClass(type) {
switch (type) {
case 2:
return CLASS_HIDE_XS_DOWN;
case 3:
return CLASS_HIDE_SM_DOWN;
case 4:
return CLASS_HIDE_MD_DOWN;
default:
return '';
}
}
/**
* Get the max ratio of a group of pointers.
* @param {string} pointers - The target pointers.
* @returns {number} The result ratio.
*/
function getMaxZoomRatio(pointers) {
var pointers2 = assign({}, pointers);
var ratios = [];
forEach(pointers, function (pointer, pointerId) {
delete pointers2[pointerId];
forEach(pointers2, function (pointer2) {
var x1 = Math.abs(pointer.startX - pointer2.startX);
var y1 = Math.abs(pointer.startY - pointer2.startY);
var x2 = Math.abs(pointer.endX - pointer2.endX);
var y2 = Math.abs(pointer.endY - pointer2.endY);
var z1 = Math.sqrt(x1 * x1 + y1 * y1);
var z2 = Math.sqrt(x2 * x2 + y2 * y2);
var ratio = (z2 - z1) / z1;
ratios.push(ratio);
});
});
ratios.sort(function (a, b) {
return Math.abs(a) < Math.abs(b);
});
return ratios[0];
}
/**
* Get a pointer from an event object.
* @param {Object} event - The target event object.
* @param {boolean} endOnly - Indicates if only returns the end point coordinate or not.
* @returns {Object} The result pointer contains start and/or end point coordinates.
*/
function getPointer(_ref2, endOnly) {
var pageX = _ref2.pageX,
pageY = _ref2.pageY;
var end = {
endX: pageX,
endY: pageY
};
return endOnly ? end : assign({
startX: pageX,
startY: pageY
}, end);
}
/**
* Get the center point coordinate of a group of pointers.
* @param {Object} pointers - The target pointers.
* @returns {Object} The center point coordinate.
*/
function getPointersCenter(pointers) {
var pageX = 0;
var pageY = 0;
var count = 0;
forEach(pointers, function (_ref3) {
var startX = _ref3.startX,
startY = _ref3.startY;
pageX += startX;
pageY += startY;
count += 1;
});
pageX /= count;
pageY /= count;
return {
pageX: pageX,
pageY: pageY
};
}
var render = {
render: function render() {
this.initContainer();
this.initViewer();
this.initList();
this.renderViewer();
},
initContainer: function initContainer() {
this.containerData = {
width: window.innerWidth,
height: window.innerHeight
};
},
initViewer: function initViewer() {
var options = this.options,
parent = this.parent;
var viewerData;
if (options.inline) {
viewerData = {
width: Math.max(parent.offsetWidth, options.minWidth),
height: Math.max(parent.offsetHeight, options.minHeight)
};
this.parentData = viewerData;
}
if (this.fulled || !viewerData) {
viewerData = this.containerData;
}
this.viewerData = assign({}, viewerData);
},
renderViewer: function renderViewer() {
if (this.options.inline && !this.fulled) {
setStyle(this.viewer, this.viewerData);
}
},
initList: function initList() {
var _this = this;
var element = this.element,
options = this.options,
list = this.list;
var items = [];
forEach(this.images, function (image, i) {
var src = image.src;
var alt = image.alt || getImageNameFromURL(src);
var url = options.url;
if (isString(url)) {
url = image.getAttribute(url);
} else if (isFunction(url)) {
url = url.call(_this, image);
}
if (src || url) {
items.push('<li>' + '<img' + " src=\"".concat(src || url, "\"") + ' role="button"' + ' data-viewer-action="view"' + " data-index=\"".concat(i, "\"") + " data-original-url=\"".concat(url || src, "\"") + " alt=\"".concat(alt, "\"") + '>' + '</li>');
}
});
list.innerHTML = items.join('');
this.items = list.getElementsByTagName('li');
forEach(this.items, function (item) {
var image = item.firstElementChild;
setData(image, 'filled', true);
if (options.loading) {
addClass(item, CLASS_LOADING);
}
addListener(image, EVENT_LOAD, function (event) {
if (options.loading) {
removeClass(item, CLASS_LOADING);
}
_this.loadImage(event);
}, {
once: true
});
});
if (options.transition) {
addListener(element, EVENT_VIEWED, function () {
addClass(list, CLASS_TRANSITION);
}, {
once: true
});
}
},
renderList: function renderList(index) {
var i = index || this.index;
var width = this.items[i].offsetWidth || 30;
var outerWidth = width + 1; // 1 pixel of `margin-left` width
// Place the active item in the center of the screen
setStyle(this.list, assign({
width: outerWidth * this.length
}, getTransforms({
translateX: (this.viewerData.width - width) / 2 - outerWidth * i
})));
},
resetList: function resetList() {
var list = this.list;
list.innerHTML = '';
removeClass(list, CLASS_TRANSITION);
setStyle(list, getTransforms({
translateX: 0
}));
},
initImage: function initImage(done) {
var _this2 = this;
var options = this.options,
image = this.image,
viewerData = this.viewerData;
var footerHeight = this.footer.offsetHeight;
var viewerWidth = viewerData.width;
var viewerHeight = Math.max(viewerData.height - footerHeight, footerHeight);
var oldImageData = this.imageData || {};
var sizingImage;
this.imageInitializing = {
abort: function abort() {
sizingImage.onload = null;
}
};
sizingImage = getImageNaturalSizes(image, function (naturalWidth, naturalHeight) {
var aspectRatio = naturalWidth / naturalHeight;
var width = viewerWidth;
var height = viewerHeight;
_this2.imageInitializing = false;
if (viewerHeight * aspectRatio > viewerWidth) {
height = viewerWidth / aspectRatio;
} else {
width = viewerHeight * aspectRatio;
}
width = Math.min(width * 0.9, naturalWidth);
height = Math.min(height * 0.9, naturalHeight);
var imageData = {
naturalWidth: naturalWidth,
naturalHeight: naturalHeight,
aspectRatio: aspectRatio,
ratio: width / naturalWidth,
width: width,
height: height,
left: (viewerWidth - width) / 2,
top: (viewerHeight - height) / 2
};
var initialImageData = assign({}, imageData);
if (options.rotatable) {
imageData.rotate = oldImageData.rotate || 0;
initialImageData.rotate = 0;
}
if (options.scalable) {
imageData.scaleX = oldImageData.scaleX || 1;
imageData.scaleY = oldImageData.scaleY || 1;
initialImageData.scaleX = 1;
initialImageData.scaleY = 1;
}
_this2.imageData = imageData;
_this2.initialImageData = initialImageData;
if (done) {
done();
}
});
},
renderImage: function renderImage(done) {
var _this3 = this;
var image = this.image,
imageData = this.imageData;
setStyle(image, assign({
width: imageData.width,
height: imageData.height,
marginLeft: imageData.left,
marginTop: imageData.top
}, getTransforms(imageData)));
if (done) {
if ((this.viewing || this.zooming) && this.options.transition) {
var onTransitionEnd = function onTransitionEnd() {
_this3.imageRendering = false;
done();
};
this.imageRendering = {
abort: function abort() {
removeListener(image, EVENT_TRANSITION_END, onTransitionEnd);
}
};
addListener(image, EVENT_TRANSITION_END, onTransitionEnd, {
once: true
});
} else {
done();
}
}
},
resetImage: function resetImage() {
// this.image only defined after viewed
if (this.viewing || this.viewed) {
var image = this.image;
if (this.viewing) {
this.viewing.abort();
}
image.parentNode.removeChild(image);
this.image = null;
}
}
};
var events = {
bind: function bind() {
var canvas = this.canvas,
element = this.element,
viewer = this.viewer;
addListener(viewer, EVENT_CLICK, this.onClick = this.click.bind(this));
addListener(viewer, EVENT_WHEEL, this.onWheel = this.wheel.bind(this));
addListener(viewer, EVENT_DRAG_START, this.onDragStart = this.dragstart.bind(this));
if (this.options.toggleOnDblclick) {
addListener(canvas, EVENT_DBLCLICK, this.onDblclick = this.dblclick.bind(this));
}
addListener(canvas, EVENT_POINTER_DOWN, this.onPointerDown = this.pointerdown.bind(this));
addListener(element.ownerDocument, EVENT_POINTER_MOVE, this.onPointerMove = this.pointermove.bind(this));
addListener(element.ownerDocument, EVENT_POINTER_UP, this.onPointerUp = this.pointerup.bind(this));
addListener(element.ownerDocument, EVENT_KEY_DOWN, this.onKeyDown = this.keydown.bind(this));
addListener(window, EVENT_RESIZE, this.onResize = this.resize.bind(this));
},
unbind: function unbind() {
var canvas = this.canvas,
element = this.element,
viewer = this.viewer;
removeListener(viewer, EVENT_CLICK, this.onClick);
removeListener(viewer, EVENT_WHEEL, this.onWheel);
removeListener(viewer, EVENT_DRAG_START, this.onDragStart);
if (this.options.toggleOnDblclick) {
removeListener(canvas, EVENT_DBLCLICK, this.onDblclick);
}
removeListener(canvas, EVENT_POINTER_DOWN, this.onPointerDown);
removeListener(element.ownerDocument, EVENT_POINTER_MOVE, this.onPointerMove);
removeListener(element.ownerDocument, EVENT_POINTER_UP, this.onPointerUp);
removeListener(element.ownerDocument, EVENT_KEY_DOWN, this.onKeyDown);
removeListener(window, EVENT_RESIZE, this.onResize);
}
};
var handlers = {
click: function click(_ref) {
var target = _ref.target;
var options = this.options,
imageData = this.imageData;
var action = getData(target, DATA_ACTION);
switch (action) {
case 'mix':
if (this.played) {
this.stop();
} else if (options.inline) {
if (this.fulled) {
this.exit();
} else {
this.full();
}
} else {
this.hide();
}
break;
case 'hide':
this.hide();
break;
case 'view':
this.view(getData(target, 'index'));
break;
case 'zoom-in':
this.zoom(0.1, true);
break;
case 'zoom-out':
this.zoom(-0.1, true);
break;
case 'one-to-one':
this.toggle();
break;
case 'reset':
this.reset();
break;
case 'prev':
this.prev(options.loop);
break;
case 'play':
this.play(options.fullscreen);
break;
case 'next':
this.next(options.loop);
break;
case 'rotate-left':
this.rotate(-90);
break;
case 'rotate-right':
this.rotate(90);
break;
case 'flip-horizontal':
this.scaleX(-imageData.scaleX || -1);
break;
case 'flip-vertical':
this.scaleY(-imageData.scaleY || -1);
break;
default:
if (this.played) {
this.stop();
}
}
},
dblclick: function dblclick(event) {
if (event.target.parentElement === this.canvas) {
this.toggle();
}
},
load: function load() {
var _this = this;
if (this.timeout) {
clearTimeout(this.timeout);
this.timeout = false;
}
var element = this.element,
options = this.options,
image = this.image,
index = this.index,
viewerData = this.viewerData;
removeClass(image, CLASS_INVISIBLE);
if (options.loading) {
removeClass(this.canvas, CLASS_LOADING);
}
image.style.cssText = 'height:0;' + "margin-left:".concat(viewerData.width / 2, "px;") + "margin-top:".concat(viewerData.height / 2, "px;") + 'max-width:none!important;' + 'position:absolute;' + 'width:0;';
this.initImage(function () {
toggleClass(image, CLASS_MOVE, options.movable);
toggleClass(image, CLASS_TRANSITION, options.transition);
_this.renderImage(function () {
_this.viewed = true;
_this.viewing = false;
if (isFunction(options.viewed)) {
addListener(element, EVENT_VIEWED, options.viewed, {
once: true
});
}
dispatchEvent(element, EVENT_VIEWED, {
originalImage: _this.images[index],
index: index,
image: image
});
});
});
},
loadImage: function loadImage(e) {
var image = e.target;
var parent = image.parentNode;
var parentWidth = parent.offsetWidth || 30;
var parentHeight = parent.offsetHeight || 50;
var filled = !!getData(image, 'filled');
getImageNaturalSizes(image, function (naturalWidth, naturalHeight) {
var aspectRatio = naturalWidth / naturalHeight;
var width = parentWidth;
var height = parentHeight;
if (parentHeight * aspectRatio > parentWidth) {
if (filled) {
width = parentHeight * aspectRatio;
} else {
height = parentWidth / aspectRatio;
}
} else if (filled) {
height = parentWidth / aspectRatio;
} else {
width = parentHeight * aspectRatio;
}
setStyle(image, assign({
width: width,
height: height
}, getTransforms({
translateX: (parentWidth - width) / 2,
translateY: (parentHeight - height) / 2
})));
});
},
keydown: function keydown(e) {
var options = this.options;
if (!this.fulled || !options.keyboard) {
return;
}
switch (e.keyCode || e.which || e.charCode) {
// Escape
case 27:
if (this.played) {
this.stop();
} else if (options.inline) {
if (this.fulled) {
this.exit();
}
} else {
this.hide();
}
break;
// Space
case 32:
if (this.played) {
this.stop();
}
break;
// ArrowLeft
case 37:
this.prev(options.loop);
break;
// ArrowUp
case 38:
// Prevent scroll on Firefox
e.preventDefault(); // Zoom in
this.zoom(options.zoomRatio, true);
break;
// ArrowRight
case 39:
this.next(options.loop);
break;
// ArrowDown
case 40:
// Prevent scroll on Firefox
e.preventDefault(); // Zoom out
this.zoom(-options.zoomRatio, true);
break;
// Ctrl + 0
case 48: // Fall through
// Ctrl + 1
// eslint-disable-next-line no-fallthrough
case 49:
if (e.ctrlKey) {
e.preventDefault();
this.toggle();
}
break;
default:
}
},
dragstart: function dragstart(e) {
if (e.target.tagName.toLowerCase() === 'img') {
e.preventDefault();
}
},
pointerdown: function pointerdown(e) {
var options = this.options,
pointers = this.pointers;
if (!this.viewed || this.showing || this.viewing || this.hiding) {
return;
} // This line is required for preventing page zooming in iOS browsers
e.preventDefault();
if (e.changedTouches) {
forEach(e.changedTouches, function (touch) {
pointers[touch.identifier] = getPointer(touch);
});
} else {
pointers[e.pointerId || 0] = getPointer(e);
}
var action = options.movable ? ACTION_MOVE : false;
if (Object.keys(pointers).length > 1) {
action = ACTION_ZOOM;
} else if ((e.pointerType === 'touch' || e.type === 'touchstart') && this.isSwitchable()) {
action = ACTION_SWITCH;
}
if (options.transition && (action === ACTION_MOVE || action === ACTION_ZOOM)) {
removeClass(this.image, CLASS_TRANSITION);
}
this.action = action;
},
pointermove: function pointermove(e) {
var pointers = this.pointers,
action = this.action;
if (!this.viewed || !action) {
return;
}
e.preventDefault();
if (e.changedTouches) {
forEach(e.changedTouches, function (touch) {
// // The first parameter should not be undefined in some browsers
assign(pointers[touch.identifier] || {}, getPointer(touch, true));
});
} else {
assign(pointers[e.pointerId || 0] || {}, getPointer(e, true));
}
this.change(e);
},
pointerup: function pointerup(e) {
var action = this.action,
pointers = this.pointers;
if (e.changedTouches) {
forEach(e.changedTouches, function (touch) {
delete pointers[touch.identifier];
});
} else {
delete pointers[e.pointerId || 0];
}
if (!action) {
return;
}
e.preventDefault();
if (this.options.transition && (action === ACTION_MOVE || action === ACTION_ZOOM)) {
addClass(this.image, CLASS_TRANSITION);
}
this.action = false;
},
resize: function resize() {
var _this2 = this;
if (!this.isShown || this.hiding) {
return;
}
this.initContainer();
this.initViewer();
this.renderViewer();
this.renderList();
if (this.viewed) {
this.initImage(function () {
_this2.renderImage();
});
}
if (this.played) {
if (this.options.fullscreen && this.fulled && !document.fullscreenElement && !document.mozFullScreenElement && !document.webkitFullscreenElement && !document.msFullscreenElement) {
this.stop();
return;
}
forEach(this.player.getElementsByTagName('img'), function (image) {
addListener(image, EVENT_LOAD, _this2.loadImage.bind(_this2), {
once: true
});
dispatchEvent(image, EVENT_LOAD);
});
}
},
wheel: function wheel(e) {
var _this3 = this;
if (!this.viewed) {
return;
}
e.preventDefault(); // Limit wheel speed to prevent zoom too fast
if (this.wheeling) {
return;
}
this.wheeling = true;
setTimeout(function () {
_this3.wheeling = false;
}, 50);
var ratio = Number(this.options.zoomRatio) || 0.1;
var delta = 1;
if (e.deltaY) {
delta = e.deltaY > 0 ? 1 : -1;
} else if (e.wheelDelta) {
delta = -e.wheelDelta / 120;
} else if (e.detail) {
delta = e.detail > 0 ? 1 : -1;
}
this.zoom(-delta * ratio, true, e);
}
};
var methods = {
/** Show the viewer (only available in modal mode)
* @param {boolean} [immediate=false] - Indicates if show the viewer immediately or not.
* @returns {Viewer} this
*/
show: function show() {
var immediate = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : false;
var element = this.element,
options = this.options;
if (options.inline || this.showing || this.isShown || this.showing) {
return this;
}
if (!this.ready) {
this.build();
if (this.ready) {
this.show(immediate);
}
return this;
}
if (isFunction(options.show)) {
addListener(element, EVENT_SHOW, options.show, {
once: true
});
}
if (dispatchEvent(element, EVENT_SHOW) === false || !this.ready) {
return this;
}
if (this.hiding) {
this.transitioning.abort();
}
this.showing = true;
this.open();
var viewer = this.viewer;
removeClass(viewer, CLASS_HIDE);
if (options.transition && !immediate) {
var shown = this.shown.bind(this);
this.transitioning = {
abort: function abort() {
removeListener(viewer, EVENT_TRANSITION_END, shown);
removeClass(viewer, CLASS_IN);
}
};
addClass(viewer, CLASS_TRANSITION); // Force reflow to enable CSS3 transition
// eslint-disable-next-line
viewer.offsetWidth;
addListener(viewer, EVENT_TRANSITION_END, shown, {
once: true
});
addClass(viewer, CLASS_IN);
} else {
addClass(viewer, CLASS_IN);
this.shown();
}
return this;
},
/**
* Hide the viewer (only available in modal mode)
* @param {boolean} [immediate=false] - Indicates if hide the viewer immediately or not.
* @returns {Viewer} this
*/
hide: function hide() {
var immediate = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : false;
var element = this.element,
options = this.options;
if (options.inline || this.hiding || !(this.isShown || this.showing)) {
return this;
}
if (isFunction(options.hide)) {
addListener(element, EVENT_HIDE, options.hide, {
once: true
});
}
if (dispatchEvent(element, EVENT_HIDE) === false) {
return this;
}
if (this.showing) {
this.transitioning.abort();
}
this.hiding = true;
if (this.played) {
this.stop();
} else if (this.viewing) {
this.viewing.abort();
}
var viewer = this.viewer;
if (options.transition && !immediate) {
var hidden = this.hidden.bind(this);
var hide = function hide() {
addListener(viewer, EVENT_TRANSITION_END, hidden, {
once: true
});
removeClass(viewer, CLASS_IN);
};
this.transitioning = {
abort: function abort() {
if (this.viewed) {
removeListener(this.image, EVENT_TRANSITION_END, hide);
} else {
removeListener(viewer, EVENT_TRANSITION_END, hidden);
}
}
};
if (this.viewed) {
addListener(this.image, EVENT_TRANSITION_END, hide, {
once: true
});
this.zoomTo(0, false, false, true);
} else {
hide();
}
} else {
removeClass(viewer, CLASS_IN);
this.hidden();
}
return this;
},
/**
* View one of the images with image's index
* @param {number} index - The index of the image to view.
* @returns {Viewer} this
*/
view: function view() {
var _this = this;
var index = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : this.options.initialViewIndex;
index = Number(index) || 0;
if (!this.isShown) {
this.index = index;
return this.show();
}
if (this.hiding || this.played || index < 0 || index >= this.length || this.viewed && index === this.index) {
return this;
}
if (this.viewing) {
this.viewing.abort();
}
var element = this.element,
options = this.options,
title = this.title,
canvas = this.canvas;
var item = this.items[index];
var img = item.querySelector('img');
var url = getData(img, 'originalUrl');
var alt = img.getAttribute('alt');
var image = document.createElement('img');
image.src = url;
image.alt = alt;
if (isFunction(options.view)) {
addListener(element, EVENT_VIEW, options.view, {
once: true
});
}
if (dispatchEvent(element, EVENT_VIEW, {
originalImage: this.images[index],
index: index,
image: image
}) === false || !this.isShown || this.hiding || this.played) {
return this;
}
this.image = image;
removeClass(this.items[this.index], CLASS_ACTIVE);
addClass(item, CLASS_ACTIVE);
this.viewed = false;
this.index = index;
this.imageData = {};
addClass(image, CLASS_INVISIBLE);
if (options.loading) {
addClass(canvas, CLASS_LOADING);
}
canvas.innerHTML = '';
canvas.appendChild(image); // Center current item
this.renderList(); // Clear title
title.innerHTML = ''; // Generate title after viewed
var onViewed = function onViewed() {
var imageData = _this.imageData;
var render = Array.isArray(options.title) ? options.title[1] : options.title;
title.innerHTML = isFunction(render) ? render.call(_this, image, imageData) : "".concat(alt, " (").concat(imageData.naturalWidth, " \xD7 ").concat(imageData.naturalHeight, ")");
};
var onLoad;
addListener(element, EVENT_VIEWED, onViewed, {
once: true
});
this.viewing = {
abort: function abort() {
removeListener(element, EVENT_VIEWED, onViewed);
if (image.complete) {
if (this.imageRendering) {
this.imageRendering.abort();
} else if (this.imageInitializing) {
this.imageInitializing.abort();
}
} else {
removeListener(image, EVENT_LOAD, onLoad);
if (this.timeout) {
clearTimeout(this.timeout);
}
}
}
};
if (image.complete) {
this.load();
} else {
addListener(image, EVENT_LOAD, onLoad = this.load.bind(this), {
once: true
});
if (this.timeout) {
clearTimeout(this.timeout);
} // Make the image visible if it fails to load within 1s
this.timeout = setTimeout(function () {
removeClass(image, CLASS_INVISIBLE);
_this.timeout = false;
}, 1000);
}
return this;
},
/**
* View the previous image
* @param {boolean} [loop=false] - Indicate if view the last one
* when it is the first one at present.
* @returns {Viewer} this
*/
prev: function prev() {
var loop = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : false;
var index = this.index - 1;
if (index < 0) {
index = loop ? this.length - 1 : 0;
}
this.view(index);
return this;
},
/**
* View the next image
* @param {boolean} [loop=false] - Indicate if view the first one
* when it is the last one at present.
* @returns {Viewer} this
*/
next: function next() {
var loop = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : false;
var maxIndex = this.length - 1;
var index = this.index + 1;
if (index > maxIndex) {
index = loop ? 0 : maxIndex;
}
this.view(index);
return this;
},
/**
* Move the image with relative offsets.
* @param {number} offsetX - The relative offset distance on the x-axis.
* @param {number} offsetY - The relative offset distance on the y-axis.
* @returns {Viewer} this
*/
move: function move(offsetX, offsetY) {
var imageData = this.imageData;
this.moveTo(isUndefined(offsetX) ? offsetX : imageData.left + Number(offsetX), isUndefined(offsetY) ? offsetY : imageData.top + Number(offsetY));
return this;
},
/**
* Move the image to an absolute point.
* @param {number} x - The x-axis coordinate.
* @param {number} [y=x] - The y-axis coordinate.
* @returns {Viewer} this
*/
moveTo: function moveTo(x) {
var y = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : x;
var imageData = this.imageData;
x = Number(x);
y = Number(y);
if (this.viewed && !this.played && this.options.movable) {
var changed = false;
if (isNumber(x)) {
imageData.left = x;
changed = true;
}
if (isNumber(y)) {
imageData.top = y;
changed = true;
}
if (changed) {
this.renderImage();
}
}
return this;
},
/**
* Zoom the image with a relative ratio.
* @param {number} ratio - The target ratio.
* @param {boolean} [hasTooltip=false] - Indicates if it has a tooltip or not.
* @param {Event} [_originalEvent=null] - The original event if any.
* @returns {Viewer} this
*/
zoom: function zoom(ratio) {
var hasTooltip = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;
var _originalEvent = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : null;
var imageData = this.imageData;
ratio = Number(ratio);
if (ratio < 0) {
ratio = 1 / (1 - ratio);
} else {
ratio = 1 + ratio;
}
this.zoomTo(imageData.width * ratio / imageData.naturalWidth, hasTooltip, _originalEvent);
return this;
},
/**
* Zoom the image to an absolute ratio.
* @param {number} ratio - The target ratio.
* @param {boolean} [hasTooltip=false] - Indicates if it has a tooltip or not.
* @param {Event} [_originalEvent=null] - The original event if any.
* @param {Event} [_zoomable=false] - Indicates if the current zoom is available or not.
* @returns {Viewer} this
*/
zoomTo: function zoomTo(ratio) {
var _this2 = this;
var hasTooltip = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;
var _originalEvent = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : null;
var _zoomable = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : false;
var element = this.element,
options = this.options,
pointers = this.pointers,
imageData = this.imageData;
ratio = Math.max(0, ratio);
if (isNumber(ratio) && this.viewed && !this.played && (_zoomable || options.zoomable)) {
if (!_zoomable) {
var minZoomRatio = Math.max(0.01, options.minZoomRatio);
var maxZoomRatio = Math.min(100, options.maxZoomRatio);
ratio = Math.min(Math.max(ratio, minZoomRatio), maxZoomRatio);
}
if (_originalEvent && ratio > 0.95 && ratio < 1.05) {
ratio = 1;
}
var newWidth = imageData.naturalWidth * ratio;
var newHeight = imageData.naturalHeight * ratio;
var oldRatio = imageData.width / imageData.naturalWidth;
if (isFunction(options.zoom)) {
addListener(element, EVENT_ZOOM, options.zoom, {
once: true
});
}
if (dispatchEvent(element, EVENT_ZOOM, {
ratio: ratio,
oldRatio: oldRatio,
originalEvent: _originalEvent
}) === false) {
return this;
}
this.zooming = true;
if (_originalEvent) {
var offset = getOffset(this.viewer);
var center = pointers && Object.keys(pointers).length ? getPointersCenter(pointers) : {
pageX: _originalEvent.pageX,
pageY: _originalEvent.pageY
}; // Zoom from the triggering point of the event
imageData.left -= (newWidth - imageData.width) * ((center.pageX - offset.left - imageData.left) / imageData.width);
imageData.top -= (newHeight - imageData.height) * ((center.pageY - offset.top - imageData.top) / imageData.height);
} else {
// Zoom from the center of the image
imageData.left -= (newWidth - imageData.width) / 2;
imageData.top -= (newHeight - imageData.height) / 2;
}
imageData.width = newWidth;
imageData.height = newHeight;
imageData.ratio = ratio;
this.renderImage(function () {
_this2.zooming = false;
if (isFunction(options.zoomed)) {
addListener(element, EVENT_ZOOMED, options.zoomed, {
once: true
});
}
dispatchEvent(element, EVENT_ZOOMED, {
ratio: ratio,
oldRatio: oldRatio,
originalEvent: _originalEvent
});
});
if (hasTooltip) {
this.tooltip();
}
}
return this;
},
/**
* Rotate the image with a relative degree.
* @param {number} degree - The rotate degree.
* @returns {Viewer} this
*/
rotate: function rotate(degree) {
this.rotateTo((this.imageData.rotate || 0) + Number(degree));
return this;
},
/**
* Rotate the image to an absolute degree.
* @param {number} degree - The rotate degree.
* @returns {Viewer} this
*/
rotateTo: function rotateTo(degree) {
var imageData = this.imageData;
degree = Number(degree);
if (isNumber(degree) && this.viewed && !this.played && this.options.rotatable) {
imageData.rotate = degree;
this.renderImage();
}
return this;
},
/**
* Scale the image on the x-axis.
* @param {number} scaleX - The scale ratio on the x-axis.
* @returns {Viewer} this
*/
scaleX: function scaleX(_scaleX) {
this.scale(_scaleX, this.imageData.scaleY);
return this;
},
/**
* Scale the image on the y-axis.
* @param {number} scaleY - The scale ratio on the y-axis.
* @returns {Viewer} this
*/
scaleY: function scaleY(_scaleY) {
this.scale(this.imageData.scaleX, _scaleY);
return this;
},
/**
* Scale the image.
* @param {number} scaleX - The scale ratio on the x-axis.
* @param {number} [scaleY=scaleX] - The scale ratio on the y-axis.
* @returns {Viewer} this
*/
scale: function scale(scaleX) {
var scaleY = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : scaleX;
var imageData = this.imageData;
scaleX = Number(scaleX);
scaleY = Number(scaleY);
if (this.viewed && !this.played && this.options.scalable) {
var changed = false;
if (isNumber(scaleX)) {
imageData.scaleX = scaleX;
changed = true;
}
if (isNumber(scaleY)) {
imageData.scaleY = scaleY;
changed = true;
}
if (changed) {
this.renderImage();
}
}
return this;
},
/**
* Play the images
* @param {boolean} [fullscreen=false] - Indicate if request fullscreen or not.
* @returns {Viewer} this
*/
play: function play() {
var _this3 = this;
var fullscreen = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : false;
if (!this.isShown || this.played) {
return this;
}
var options = this.options,
player = this.player;
var onLoad = this.loadImage.bind(this);
var list = [];
var total = 0;
var index = 0;
this.played = true;
this.onLoadWhenPlay = onLoad;
if (fullscreen) {
this.requestFullscreen();
}
addClass(player, CLASS_SHOW);
forEach(this.items, function (item, i) {
var img = item.querySelector('img');
var image = document.createElement('img');
image.src = getData(img, 'originalUrl');
image.alt = img.getAttribute('alt');
total += 1;
addClass(image, CLASS_FADE);
toggleClass(image, CLASS_TRANSITION, options.transition);
if (hasClass(item, CLASS_ACTIVE)) {
addClass(image, CLASS_IN);
index = i;
}
list.push(image);
addListener(image, EVENT_LOAD, onLoad, {
once: true
});
player.appendChild(image);
});
if (isNumber(options.interval) && options.interval > 0) {
var play = function play() {
_this3.playing = setTimeout(function () {
removeClass(list[index], CLASS_IN);
index += 1;
index = index < total ? index : 0;
addClass(list[index], CLASS_IN);
play();
}, options.interval);
};
if (total > 1) {
play();
}
}
return this;
},
// Stop play
stop: function stop() {
var _this4 = this;
if (!this.played) {
return this;
}
var player = this.player;
this.played = false;
clearTimeout(this.playing);
forEach(player.getElementsByTagName('img'), function (image) {
removeListener(image, EVENT_LOAD, _this4.onLoadWhenPlay);
});
removeClass(player, CLASS_SHOW);
player.innerHTML = '';
this.exitFullscreen();
return this;
},
// Enter modal mode (only available in inline mode)
full: function full() {
var _this5 = this;
var options = this.options,
viewer = this.viewer,
image = this.image,
list = this.list;
if (!this.isShown || this.played || this.fulled || !options.inline) {
return this;
}
this.fulled = true;
this.open();
addClass(this.button, CLASS_FULLSCREEN_EXIT);
if (options.transition) {
removeClass(list, CLASS_TRANSITION);
if (this.viewed) {
removeClass(image, CLASS_TRANSITION);
}
}
addClass(viewer, CLASS_FIXED);
viewer.setAttribute('style', '');
setStyle(viewer, {
zIndex: options.zIndex
});
this.initContainer();
this.viewerData = assign({}, this.containerData);
this.renderList();
if (this.viewed) {
this.initImage(function () {
_this5.renderImage(function () {
if (options.transition) {
setTimeout(function () {
addClass(image, CLASS_TRANSITION);
addClass(list, CLASS_TRANSITION);
}, 0);
}
});
});
}
return this;
},
// Exit modal mode (only available in inline mode)
exit: function exit() {
var _this6 = this;
var options = this.options,
viewer = this.viewer,
image = this.image,
list = this.list;
if (!this.isShown || this.played || !this.fulled || !options.inline) {
return this;
}
this.fulled = false;
this.close();
removeClass(this.button, CLASS_FULLSCREEN_EXIT);
if (options.transition) {
removeClass(list, CLASS_TRANSITION);
if (this.viewed) {
removeClass(image, CLASS_TRANSITION);
}
}
removeClass(viewer, CLASS_FIXED);
setStyle(viewer, {
zIndex: options.zIndexInline
});
this.viewerData = assign({}, this.parentData);
this.renderViewer();
this.renderList();
if (this.viewed) {
this.initImage(function () {
_this6.renderImage(function () {
if (options.transition) {
setTimeout(function () {
addClass(image, CLASS_TRANSITION);
addClass(list, CLASS_TRANSITION);
}, 0);
}
});
});
}
return this;
},
// Show the current ratio of the image with percentage
tooltip: function tooltip() {
var _this7 = this;
var options = this.options,
tooltipBox = this.tooltipBox,
imageData = this.imageData;
if (!this.viewed || this.played || !options.tooltip) {
return this;
}
tooltipBox.textContent = "".concat(Math.round(imageData.ratio * 100), "%");
if (!this.tooltipping) {
if (options.transition) {
if (this.fading) {
dispatchEvent(tooltipBox, EVENT_TRANSITION_END);
}
addClass(tooltipBox, CLASS_SHOW);
addClass(tooltipBox, CLASS_FADE);
addClass(tooltipBox, CLASS_TRANSITION); // Force reflow to enable CSS3 transition
// eslint-disable-next-line
tooltipBox.offsetWidth;
addClass(tooltipBox, CLASS_IN);
} else {
addClass(tooltipBox, CLASS_SHOW);
}
} else {
clearTimeout(this.tooltipping);
}
this.tooltipping = setTimeout(function () {
if (options.transition) {
addListener(tooltipBox, EVENT_TRANSITION_END, function () {
removeClass(tooltipBox, CLASS_SHOW);
removeClass(tooltipBox, CLASS_FADE);
removeClass(tooltipBox, CLASS_TRANSITION);
_this7.fading = false;
}, {
once: true
});
removeClass(tooltipBox, CLASS_IN);
_this7.fading = true;
} else {
removeClass(tooltipBox, CLASS_SHOW);
}
_this7.tooltipping = false;
}, 1000);
return this;
},
// Toggle the image size between its natural size and initial size
toggle: function toggle() {
if (this.imageData.ratio === 1) {
this.zoomTo(this.initialImageData.ratio, true);
} else {
this.zoomTo(1, true);
}
return this;
},
// Reset the image to its initial state
reset: function reset() {
if (this.viewed && !this.played) {
this.imageData = assign({}, this.initialImageData);
this.renderImage();
}
return this;
},
// Update viewer when images changed
update: function update() {
var element = this.element,
options = this.options,
isImg = this.isImg; // Destroy viewer if the target image was deleted
if (isImg && !element.parentNode) {
return this.destroy();
}
var images = [];
forEach(isImg ? [element] : element.querySelectorAll('img'), function (image) {
if (options.filter) {
if (options.filter(image)) {
images.push(image);
}
} else {
images.push(image);
}
});
if (!images.length) {
return this;
}
this.images = images;
this.length = images.length;
if (this.ready) {
var indexes = [];
forEach(this.items, function (item, i) {
var img = item.querySelector('img');
var image = images[i];
if (image) {
if (image.src !== img.src) {
indexes.push(i);
}
} else {
indexes.push(i);
}
});
setStyle(this.list, {
width: 'auto'
});
this.initList();
if (this.isShown) {
if (this.length) {
if (this.viewed) {
var index = indexes.indexOf(this.index);
if (index >= 0) {
this.viewed = false;
this.view(Math.max(this.index - (index + 1), 0));
} else {
addClass(this.items[this.index], CLASS_ACTIVE);
}
}
} else {
this.image = null;
this.viewed = false;
this.index = 0;
this.imageData = {};
this.canvas.innerHTML = '';
this.title.innerHTML = '';
}
}
} else {
this.build();
}
return this;
},
// Destroy the viewer
destroy: function destroy() {
var element = this.element,
options = this.options;
if (!element[NAMESPACE]) {
return this;
}
this.destroyed = true;
if (this.ready) {
if (this.played) {
this.stop();
}
if (options.inline) {
if (this.fulled) {
this.exit();
}
this.unbind();
} else if (this.isShown) {
if (this.viewing) {
if (this.imageRendering) {
this.imageRendering.abort();
} else if (this.imageInitializing) {
this.imageInitializing.abort();
}
}
if (this.hiding) {
this.transitioning.abort();
}
this.hidden();
} else if (this.showing) {
this.transitioning.abort();
this.hidden();
}
this.ready = false;
this.viewer.parentNode.removeChild(this.viewer);
} else if (options.inline) {
if (this.delaying) {
this.delaying.abort();
} else if (this.initializing) {
this.initializing.abort();
}
}
if (!options.inline) {
removeListener(element, EVENT_CLICK, this.onStart);
}
element[NAMESPACE] = undefined;
return this;
}
};
var others = {
open: function open() {
var body = this.body;
addClass(body, CLASS_OPEN);
body.style.paddingRight = "".concat(this.scrollbarWidth + (parseFloat(this.initialBodyPaddingRight) || 0), "px");
},
close: function close() {
var body = this.body;
removeClass(body, CLASS_OPEN);
body.style.paddingRight = this.initialBodyPaddingRight;
},
shown: function shown() {
var element = this.element,
options = this.options;
this.fulled = true;
this.isShown = true;
this.render();
this.bind();
this.showing = false;
if (isFunction(options.shown)) {
addListener(element, EVENT_SHOWN, options.shown, {
once: true
});
}
if (dispatchEvent(element, EVENT_SHOWN) === false) {
return;
}
if (this.ready && this.isShown && !this.hiding) {
this.view(this.index);
}
},
hidden: function hidden() {
var element = this.element,
options = this.options;
this.fulled = false;
this.viewed = false;
this.isShown = false;
this.close();
this.unbind();
addClass(this.viewer, CLASS_HIDE);
this.resetList();
this.resetImage();
this.hiding = false;
if (!this.destroyed) {
if (isFunction(options.hidden)) {
addListener(element, EVENT_HIDDEN, options.hidden, {
once: true
});
}
dispatchEvent(element, EVENT_HIDDEN);
}
},
requestFullscreen: function requestFullscreen() {
var document = this.element.ownerDocument;
if (this.fulled && !document.fullscreenElement && !document.mozFullScreenElement && !document.webkitFullscreenElement && !document.msFullscreenElement) {
var documentElement = document.documentElement;
if (documentElement.requestFullscreen) {
documentElement.requestFullscreen();
} else if (documentElement.msRequestFullscreen) {
documentElement.msRequestFullscreen();
} else if (documentElement.mozRequestFullScreen) {
documentElement.mozRequestFullScreen();
} else if (documentElement.webkitRequestFullscreen) {
documentElement.webkitRequestFullscreen(Element.ALLOW_KEYBOARD_INPUT);
}
}
},
exitFullscreen: function exitFullscreen() {
if (this.fulled) {
var document = this.element.ownerDocument;
if (document.exitFullscreen) {
document.exitFullscreen();
} else if (document.msExitFullscreen) {
document.msExitFullscreen();
} else if (document.mozCancelFullScreen) {
document.mozCancelFullScreen();
} else if (document.webkitExitFullscreen) {
document.webkitExitFullscreen();
}
}
},
change: function change(e) {
var options = this.options,
pointers = this.pointers;
var pointer = pointers[Object.keys(pointers)[0]];
var offsetX = pointer.endX - pointer.startX;
var offsetY = pointer.endY - pointer.startY;
switch (this.action) {
// Move the current image
case ACTION_MOVE:
this.move(offsetX, offsetY);
break;
// Zoom the current image
case ACTION_ZOOM:
this.zoom(getMaxZoomRatio(pointers), false, e);
break;
case ACTION_SWITCH:
{
this.action = 'switched';
var absoluteOffsetX = Math.abs(offsetX);
if (absoluteOffsetX > 1 && absoluteOffsetX > Math.abs(offsetY)) {
// Empty `pointers` as `touchend` event will not be fired after swiped in iOS browsers.
this.pointers = {};
if (offsetX > 1) {
this.prev(options.loop);
} else if (offsetX < -1) {
this.next(options.loop);
}
}
break;
}
default:
} // Override
forEach(pointers, function (p) {
p.startX = p.endX;
p.startY = p.endY;
});
},
isSwitchable: function isSwitchable() {
var imageData = this.imageData,
viewerData = this.viewerData;
return this.length > 1 && imageData.left >= 0 && imageData.top >= 0 && imageData.width <= viewerData.width && imageData.height <= viewerData.height;
}
};
var AnotherViewer = WINDOW.Viewer;
var Viewer =
/*#__PURE__*/
function () {
/**
* Create a new Viewer.
* @param {Element} element - The target element for viewing.
* @param {Object} [options={}] - The configuration options.
*/
function Viewer(element) {
var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
_classCallCheck(this, Viewer);
if (!element || element.nodeType !== 1) {
throw new Error('The first argument is required and must be an element.');
}
this.element = element;
this.options = assign({}, DEFAULTS, isPlainObject(options) && options);
this.action = false;
this.fading = false;
this.fulled = false;
this.hiding = false;
this.imageData = {};
this.index = this.options.initialViewIndex;
this.isImg = false;
this.isShown = false;
this.length = 0;
this.played = false;
this.playing = false;
this.pointers = {};
this.ready = false;
this.showing = false;
this.timeout = false;
this.tooltipping = false;
this.viewed = false;
this.viewing = false;
this.wheeling = false;
this.zooming = false;
this.init();
}
_createClass(Viewer, [{
key: "init",
value: function init() {
var _this = this;
var element = this.element,
options = this.options;
if (element[NAMESPACE]) {
return;
}
element[NAMESPACE] = this;
var isImg = element.tagName.toLowerCase() === 'img';
var images = [];
forEach(isImg ? [element] : element.querySelectorAll('img'), function (image) {
if (isFunction(options.filter)) {
if (options.filter.call(_this, image)) {
images.push(image);
}
} else {
images.push(image);
}
});
if (!images.length) {
return;
}
this.isImg = isImg;
this.length = images.length;
this.images = images;
var ownerDocument = element.ownerDocument;
var body = ownerDocument.body || ownerDocument.documentElement;
this.body = body;
this.scrollbarWidth = window.innerWidth - ownerDocument.documentElement.clientWidth;
this.initialBodyPaddingRight = window.getComputedStyle(body).paddingRight; // Override `transition` option if it is not supported
if (isUndefined(document.createElement(NAMESPACE).style.transition)) {
options.transition = false;
}
if (options.inline) {
var count = 0;
var progress = function progress() {
count += 1;
if (count === _this.length) {
var timeout;
_this.initializing = false;
_this.delaying = {
abort: function abort() {
clearTimeout(timeout);
}
}; // build asynchronously to keep `this.viewer` is accessible in `ready` event handler.
timeout = setTimeout(function () {
_this.delaying = false;
_this.build();
}, 0);
}
};
this.initializing = {
abort: function abort() {
forEach(images, function (image) {
if (!image.complete) {
removeListener(image, EVENT_LOAD, progress);
}
});
}
};
forEach(images, function (image) {
if (image.complete) {
progress();
} else {
addListener(image, EVENT_LOAD, progress, {
once: true
});
}
});
} else {
addListener(element, EVENT_CLICK, this.onStart = function (_ref) {
var target = _ref.target;
if (target.tagName.toLowerCase() === 'img' && (!isFunction(options.filter) || options.filter.call(_this, target))) {
_this.view(_this.images.indexOf(target));
}
});
}
}
}, {
key: "build",
value: function build() {
if (this.ready) {
return;
}
var element = this.element,
options = this.options;
var parent = element.parentNode;
var template = document.createElement('div');
template.innerHTML = TEMPLATE;
var viewer = template.querySelector(".".concat(NAMESPACE, "-container"));
var title = viewer.querySelector(".".concat(NAMESPACE, "-title"));
var toolbar = viewer.querySelector(".".concat(NAMESPACE, "-toolbar"));
var navbar = viewer.querySelector(".".concat(NAMESPACE, "-navbar"));
var button = viewer.querySelector(".".concat(NAMESPACE, "-button"));
var canvas = viewer.querySelector(".".concat(NAMESPACE, "-canvas"));
this.parent = parent;
this.viewer = viewer;
this.title = title;
this.toolbar = toolbar;
this.navbar = navbar;
this.button = button;
this.canvas = canvas;
this.footer = viewer.querySelector(".".concat(NAMESPACE, "-footer"));
this.tooltipBox = viewer.querySelector(".".concat(NAMESPACE, "-tooltip"));
this.player = viewer.querySelector(".".concat(NAMESPACE, "-player"));
this.list = viewer.querySelector(".".concat(NAMESPACE, "-list"));
addClass(title, !options.title ? CLASS_HIDE : getResponsiveClass(Array.isArray(options.title) ? options.title[0] : options.title));
addClass(navbar, !options.navbar ? CLASS_HIDE : getResponsiveClass(options.navbar));
toggleClass(button, CLASS_HIDE, !options.button);
if (options.backdrop) {
addClass(viewer, "".concat(NAMESPACE, "-backdrop"));
if (!options.inline && options.backdrop === true) {
setData(canvas, DATA_ACTION, 'hide');
}
}
if (isString(options.className) && options.className) {
// In case there are multiple class names
options.className.split(REGEXP_SPACES).forEach(function (className) {
addClass(viewer, className);
});
}
if (options.toolbar) {
var list = document.createElement('ul');
var custom = isPlainObject(options.toolbar);
var zoomButtons = BUTTONS.slice(0, 3);
var rotateButtons = BUTTONS.slice(7, 9);
var scaleButtons = BUTTONS.slice(9);
if (!custom) {
addClass(toolbar, getResponsiveClass(options.toolbar));
}
forEach(custom ? options.toolbar : BUTTONS, function (value, index) {
var deep = custom && isPlainObject(value);
var name = custom ? hyphenate(index) : value;
var show = deep && !isUndefined(value.show) ? value.show : value;
if (!show || !options.zoomable && zoomButtons.indexOf(name) !== -1 || !options.rotatable && rotateButtons.indexOf(name) !== -1 || !options.scalable && scaleButtons.indexOf(name) !== -1) {
return;
}
var size = deep && !isUndefined(value.size) ? value.size : value;
var click = deep && !isUndefined(value.click) ? value.click : value;
var item = document.createElement('li');
item.setAttribute('role', 'button');
addClass(item, "".concat(NAMESPACE, "-").concat(name));
if (!isFunction(click)) {
setData(item, DATA_ACTION, name);
}
if (isNumber(show)) {
addClass(item, getResponsiveClass(show));
}
if (['small', 'large'].indexOf(size) !== -1) {
addClass(item, "".concat(NAMESPACE, "-").concat(size));
} else if (name === 'play') {
addClass(item, "".concat(NAMESPACE, "-large"));
}
if (isFunction(click)) {
addListener(item, EVENT_CLICK, click);
}
list.appendChild(item);
});
toolbar.appendChild(list);
} else {
addClass(toolbar, CLASS_HIDE);
}
if (!options.rotatable) {
var rotates = toolbar.querySelectorAll('li[class*="rotate"]');
addClass(rotates, CLASS_INVISIBLE);
forEach(rotates, function (rotate) {
toolbar.appendChild(rotate);
});
}
if (options.inline) {
addClass(button, CLASS_FULLSCREEN);
setStyle(viewer, {
zIndex: options.zIndexInline
});
if (window.getComputedStyle(parent).position === 'static') {
setStyle(parent, {
position: 'relative'
});
}
parent.insertBefore(viewer, element.nextSibling);
} else {
addClass(button, CLASS_CLOSE);
addClass(viewer, CLASS_FIXED);
addClass(viewer, CLASS_FADE);
addClass(viewer, CLASS_HIDE);
setStyle(viewer, {
zIndex: options.zIndex
});
var container = options.container;
if (isString(container)) {
container = element.ownerDocument.querySelector(container);
}
if (!container) {
container = this.body;
}
container.appendChild(viewer);
}
if (options.inline) {
this.render();
this.bind();
this.isShown = true;
}
this.ready = true;
if (isFunction(options.ready)) {
addListener(element, EVENT_READY, options.ready, {
once: true
});
}
if (dispatchEvent(element, EVENT_READY) === false) {
this.ready = false;
return;
}
if (this.ready && options.inline) {
this.view(this.index);
}
}
/**
* Get the no conflict viewer class.
* @returns {Viewer} The viewer class.
*/
}], [{
key: "noConflict",
value: function noConflict() {
window.Viewer = AnotherViewer;
return Viewer;
}
/**
* Change the default options.
* @param {Object} options - The new default options.
*/
}, {
key: "setDefaults",
value: function setDefaults(options) {
assign(DEFAULTS, isPlainObject(options) && options);
}
}]);
return Viewer;
}();
assign(Viewer.prototype, render, events, handlers, methods, others);
module.exports = Viewer;
/*!
* Viewer.js v1.3.0
* https://fengyuanchen.github.io/viewerjs
*
* Copyright 2015-present Chen Fengyuan
* Released under the MIT license
*
* Date: 2018-10-25T12:41:52.459Z
*/
.viewer-zoom-in::before,
.viewer-zoom-out::before,
.viewer-one-to-one::before,
.viewer-reset::before,
.viewer-prev::before,
.viewer-play::before,
.viewer-next::before,
.viewer-rotate-left::before,
.viewer-rotate-right::before,
.viewer-flip-horizontal::before,
.viewer-flip-vertical::before,
.viewer-fullscreen::before,
.viewer-fullscreen-exit::before,
.viewer-close::before {
background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAARgAAAAUCAYAAABWOyJDAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAALEgAACxIB0t1+/AAAABx0RVh0U29mdHdhcmUAQWRvYmUgRmlyZXdvcmtzIENTNui8sowAAAQPSURBVHic7Zs/iFxVFMa/0U2UaJGksUgnIVhYxVhpjDbZCBmLdAYECxsRFBTUamcXUiSNncgKQbSxsxH8gzAP3FU2jY0kKKJNiiiIghFlccnP4p3nPCdv3p9778vsLOcHB2bfveeb7955c3jvvNkBIMdxnD64a94GHMfZu3iBcRynN7zAOI7TG15gHCeeNUkr8zaxG2lbYDYsdgMbktBsP03jdQwljSXdtBhLOmtjowC9Mg9L+knSlcD8TNKpSA9lBpK2JF2VdDSR5n5J64m0qli399hNFMUlpshQii5jbXTbHGviB0nLNeNDSd9VO4A2UdB2fp+x0eCnaXxWXGA2X0au/3HgN9P4LFCjIANOJdrLr0zzZ+BEpNYDwKbpnQMeAw4m8HjQtM6Z9qa917zPQwFr3M5KgA6J5rTJCdFZJj9/lyvGhsDvwFNVuV2MhhjrK6b9bFiE+j1r87eBl4HDwCF7/U/k+ofAX5b/EXBv5JoLMuILzf3Ap6Z3EzgdqHMCuF7hcQf4HDgeoHnccncqdK/TvSDWffFXI/exICY/xZyqc6XLWF1UFZna4gJ7q8BsRvgd2/xXpo6P+D9dfT7PpECtA3cnWPM0GXGFZh/wgWltA+cDNC7X+AP4GzjZQe+k5dRxuYPeiuXU7e1qwLpDz7dFjXKRaSwuMLvAlG8zZlG+YmiK1HoFqT7wP2z+4Q45TfEGcMt01xLoNZEBTwRqD4BLpnMLeC1A41UmVxsXgXeBayV/Wx20rpTyrpnWRft7p6O/FdqzGrDukPNtkaMoMo3FBdBSQMOnYBCReyf05s126fU9ytfX98+mY54Kxnp7S9K3kj6U9KYdG0h6UdLbkh7poFXMfUnSOyVvL0h6VtIXHbS6nOP+s/Zm9mvyXW1uuC9ohZ72E9uDmXWLJOB1GxsH+DxPftsB8B6wlGDN02TAkxG6+4D3TWsbeC5CS8CDFce+AW500LhhOW2020TRjK3b21HEmgti9m0RonxbdMZeVzV+/4tF3cBpP7E9mKHNL5q8h5g0eYsCMQz0epq8gQrwMXAgcs0FGXGFRcB9wCemF9PkbYqM/Bas7fxLwNeJPdTdpo4itQti8lPMqTpXuozVRVXPpbHI3KkNTB1NfkL81j2mvhDp91HgV9MKuRIqrykj3WPq4rHyL+axj8/qGPmTqi6F9YDlHOvJU6oYcTsh/TYSzWmTE6JT19CtLTJt32D6CmHe0eQn1O8z5AXgT4sx4Vcu0/EQecMydB8z0hUWkTd2t4CrwNEePqMBcAR4mrBbwyXLPWJa8zrXmmLEhNBmfpkuY2102xxrih+pb+ieAb6vGhuA97UcJ5KR8gZ77K+99xxeYBzH6Q3/Z0fHcXrDC4zjOL3hBcZxnN74F+zlvXFWXF9PAAAAAElFTkSuQmCC');
background-repeat: no-repeat;
color: transparent;
display: block;
font-size: 0;
height: 20px;
line-height: 0;
width: 20px;
}
.viewer-zoom-in::before {
background-position: 0 0;
content: 'Zoom In';
}
.viewer-zoom-out::before {
background-position: -20px 0;
content: 'Zoom Out';
}
.viewer-one-to-one::before {
background-position: -40px 0;
content: 'One to One';
}
.viewer-reset::before {
background-position: -60px 0;
content: 'Reset';
}
.viewer-prev::before {
background-position: -80px 0;
content: 'Previous';
}
.viewer-play::before {
background-position: -100px 0;
content: 'Play';
}
.viewer-next::before {
background-position: -120px 0;
content: 'Next';
}
.viewer-rotate-left::before {
background-position: -140px 0;
content: 'Rotate Left';
}
.viewer-rotate-right::before {
background-position: -160px 0;
content: 'Rotate Right';
}
.viewer-flip-horizontal::before {
background-position: -180px 0;
content: 'Flip Horizontal';
}
.viewer-flip-vertical::before {
background-position: -200px 0;
content: 'Flip Vertical';
}
.viewer-fullscreen::before {
background-position: -220px 0;
content: 'Enter Full Screen';
}
.viewer-fullscreen-exit::before {
background-position: -240px 0;
content: 'Exit Full Screen';
}
.viewer-close::before {
background-position: -260px 0;
content: 'Close';
}
.viewer-container {
bottom: 0;
direction: ltr;
font-size: 0;
left: 0;
line-height: 0;
overflow: hidden;
position: absolute;
right: 0;
-webkit-tap-highlight-color: transparent;
top: 0;
-webkit-touch-callout: none;
-ms-touch-action: none;
touch-action: none;
-webkit-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
}
.viewer-container::-moz-selection,
.viewer-container *::-moz-selection {
background-color: transparent;
}
.viewer-container::selection,
.viewer-container *::selection {
background-color: transparent;
}
.viewer-container img {
display: block;
height: auto;
max-height: none !important;
max-width: none !important;
min-height: 0 !important;
min-width: 0 !important;
width: 100%;
}
.viewer-canvas {
bottom: 0;
left: 0;
overflow: hidden;
position: absolute;
right: 0;
top: 0;
}
.viewer-canvas > img {
height: auto;
margin: 15px auto;
max-width: 90% !important;
width: auto;
}
.viewer-footer {
bottom: 0;
left: 0;
overflow: hidden;
position: absolute;
right: 0;
text-align: center;
}
.viewer-navbar {
background-color: rgba(0, 0, 0, .5);
overflow: hidden;
}
.viewer-list {
-webkit-box-sizing: content-box;
box-sizing: content-box;
height: 50px;
margin: 0;
overflow: hidden;
padding: 1px 0;
}
.viewer-list > li {
color: transparent;
cursor: pointer;
float: left;
font-size: 0;
height: 50px;
line-height: 0;
opacity: .5;
overflow: hidden;
-webkit-transition: opacity .15s;
transition: opacity .15s;
width: 30px;
}
.viewer-list > li:hover {
opacity: .75;
}
.viewer-list > li + li {
margin-left: 1px;
}
.viewer-list > .viewer-loading {
position: relative;
}
.viewer-list > .viewer-loading::after {
border-width: 2px;
height: 20px;
margin-left: -10px;
margin-top: -10px;
width: 20px;
}
.viewer-list > .viewer-active,
.viewer-list > .viewer-active:hover {
opacity: 1;
}
.viewer-player {
background-color: #000;
bottom: 0;
cursor: none;
display: none;
left: 0;
position: absolute;
right: 0;
top: 0;
}
.viewer-player > img {
left: 0;
position: absolute;
top: 0;
}
.viewer-toolbar > ul {
display: inline-block;
margin: 0 auto 5px;
overflow: hidden;
padding: 3px 0;
}
.viewer-toolbar > ul > li {
background-color: rgba(0, 0, 0, .5);
border-radius: 50%;
cursor: pointer;
float: left;
height: 24px;
overflow: hidden;
-webkit-transition: background-color .15s;
transition: background-color .15s;
width: 24px;
}
.viewer-toolbar > ul > li:hover {
background-color: rgba(0, 0, 0, .8);
}
.viewer-toolbar > ul > li::before {
margin: 2px;
}
.viewer-toolbar > ul > li + li {
margin-left: 1px;
}
.viewer-toolbar > ul > .viewer-small {
height: 18px;
margin-bottom: 3px;
margin-top: 3px;
width: 18px;
}
.viewer-toolbar > ul > .viewer-small::before {
margin: -1px;
}
.viewer-toolbar > ul > .viewer-large {
height: 30px;
margin-bottom: -3px;
margin-top: -3px;
width: 30px;
}
.viewer-toolbar > ul > .viewer-large::before {
margin: 5px;
}
.viewer-tooltip {
background-color: rgba(0, 0, 0, 0.8);
border-radius: 10px;
color: #fff;
display: none;
font-size: 12px;
height: 20px;
left: 50%;
line-height: 20px;
margin-left: -25px;
margin-top: -10px;
position: absolute;
text-align: center;
top: 50%;
width: 50px;
}
.viewer-title {
color: #ccc;
display: inline-block;
font-size: 12px;
line-height: 1;
margin: 0 5% 5px;
max-width: 90%;
opacity: .8;
overflow: hidden;
text-overflow: ellipsis;
-webkit-transition: opacity .15s;
transition: opacity .15s;
white-space: nowrap;
}
.viewer-title:hover {
opacity: 1;
}
.viewer-button {
background-color: rgba(0, 0, 0, .5);
border-radius: 50%;
cursor: pointer;
height: 80px;
overflow: hidden;
position: absolute;
right: -40px;
top: -40px;
-webkit-transition: background-color .15s;
transition: background-color .15s;
width: 80px;
}
.viewer-button:focus,
.viewer-button:hover {
background-color: rgba(0, 0, 0, .8);
}
.viewer-button::before {
bottom: 15px;
left: 15px;
position: absolute;
}
.viewer-fixed {
position: fixed;
}
.viewer-open {
overflow: hidden;
}
.viewer-show {
display: block;
}
.viewer-hide {
display: none;
}
.viewer-backdrop {
background-color: rgba(0, 0, 0, .5);
}
.viewer-invisible {
visibility: hidden;
}
.viewer-move {
cursor: move;
cursor: -webkit-grab;
cursor: grab;
}
.viewer-fade {
opacity: 0;
}
.viewer-in {
opacity: 1;
}
.viewer-transition {
-webkit-transition: all .3s;
transition: all .3s;
}
@-webkit-keyframes viewer-spinner {
0% {
-webkit-transform: rotate(0deg);
transform: rotate(0deg);
}
100% {
-webkit-transform: rotate(360deg);
transform: rotate(360deg);
}
}
@keyframes viewer-spinner {
0% {
-webkit-transform: rotate(0deg);
transform: rotate(0deg);
}
100% {
-webkit-transform: rotate(360deg);
transform: rotate(360deg);
}
}
.viewer-loading::after {
-webkit-animation: viewer-spinner 1s linear infinite;
animation: viewer-spinner 1s linear infinite;
border: 4px solid rgba(255, 255, 255, .1);
border-left-color: rgba(255, 255, 255, .5);
border-radius: 50%;
content: '';
display: inline-block;
height: 40px;
left: 50%;
margin-left: -20px;
margin-top: -20px;
position: absolute;
top: 50%;
width: 40px;
z-index: 1;
}
@media (max-width: 767px) {
.viewer-hide-xs-down {
display: none;
}
}
@media (max-width: 991px) {
.viewer-hide-sm-down {
display: none;
}
}
@media (max-width: 1199px) {
.viewer-hide-md-down {
display: none;
}
}
/*!
* Viewer.js v1.3.0
* https://fengyuanchen.github.io/viewerjs
*
* Copyright 2015-present Chen Fengyuan
* Released under the MIT license
*
* Date: 2018-10-25T12:41:54.899Z
*/
function _typeof(obj) {
if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") {
_typeof = function (obj) {
return typeof obj;
};
} else {
_typeof = function (obj) {
return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj;
};
}
return _typeof(obj);
}
function _classCallCheck(instance, Constructor) {
if (!(instance instanceof Constructor)) {
throw new TypeError("Cannot call a class as a function");
}
}
function _defineProperties(target, props) {
for (var i = 0; i < props.length; i++) {
var descriptor = props[i];
descriptor.enumerable = descriptor.enumerable || false;
descriptor.configurable = true;
if ("value" in descriptor) descriptor.writable = true;
Object.defineProperty(target, descriptor.key, descriptor);
}
}
function _createClass(Constructor, protoProps, staticProps) {
if (protoProps) _defineProperties(Constructor.prototype, protoProps);
if (staticProps) _defineProperties(Constructor, staticProps);
return Constructor;
}
var DEFAULTS = {
/**
* Enable a modal backdrop, specify `static` for a backdrop
* which doesn't close the modal on click.
* @type {boolean}
*/
backdrop: true,
/**
* Show the button on the top-right of the viewer.
* @type {boolean}
*/
button: true,
/**
* Show the navbar.
* @type {boolean | number}
*/
navbar: true,
/**
* Specify the visibility and the content of the title.
* @type {boolean | number | Function | Array}
*/
title: true,
/**
* Show the toolbar.
* @type {boolean | number | Object}
*/
toolbar: true,
/**
* Custom class name(s) to add to the viewer's root element.
* @type {string}
*/
className: '',
/**
* Define where to put the viewer in modal mode.
* @type {string | Element}
*/
container: 'body',
/**
* Filter the images for viewing. Return true if the image is viewable.
* @type {Function}
*/
filter: null,
/**
* Enable to request fullscreen when play.
* @type {boolean}
*/
fullscreen: true,
/**
* Define the initial index of image for viewing.
* @type {number}
*/
initialViewIndex: 0,
/**
* Enable inline mode.
* @type {boolean}
*/
inline: false,
/**
* The amount of time to delay between automatically cycling an image when playing.
* @type {number}
*/
interval: 5000,
/**
* Enable keyboard support.
* @type {boolean}
*/
keyboard: true,
/**
* Indicate if show a loading spinner when load image or not.
* @type {boolean}
*/
loading: true,
/**
* Indicate if enable loop viewing or not.
* @type {boolean}
*/
loop: true,
/**
* Min width of the viewer in inline mode.
* @type {number}
*/
minWidth: 200,
/**
* Min height of the viewer in inline mode.
* @type {number}
*/
minHeight: 100,
/**
* Enable to move the image.
* @type {boolean}
*/
movable: true,
/**
* Enable to zoom the image.
* @type {boolean}
*/
zoomable: true,
/**
* Enable to rotate the image.
* @type {boolean}
*/
rotatable: true,
/**
* Enable to scale the image.
* @type {boolean}
*/
scalable: true,
/**
* Indicate if toggle the image size between its natural size
* and initial size when double click on the image or not.
* @type {boolean}
*/
toggleOnDblclick: true,
/**
* Show the tooltip with image ratio (percentage) when zoom in or zoom out.
* @type {boolean}
*/
tooltip: true,
/**
* Enable CSS3 Transition for some special elements.
* @type {boolean}
*/
transition: true,
/**
* Define the CSS `z-index` value of viewer in modal mode.
* @type {number}
*/
zIndex: 2015,
/**
* Define the CSS `z-index` value of viewer in inline mode.
* @type {number}
*/
zIndexInline: 0,
/**
* Define the ratio when zoom the image by wheeling mouse.
* @type {number}
*/
zoomRatio: 0.1,
/**
* Define the min ratio of the image when zoom out.
* @type {number}
*/
minZoomRatio: 0.01,
/**
* Define the max ratio of the image when zoom in.
* @type {number}
*/
maxZoomRatio: 100,
/**
* Define where to get the original image URL for viewing.
* @type {string | Function}
*/
url: 'src',
/**
* Event shortcuts.
* @type {Function}
*/
ready: null,
show: null,
shown: null,
hide: null,
hidden: null,
view: null,
viewed: null,
zoom: null,
zoomed: null
};
var TEMPLATE = '<div class="viewer-container" touch-action="none">' + '<div class="viewer-canvas"></div>' + '<div class="viewer-footer">' + '<div class="viewer-title"></div>' + '<div class="viewer-toolbar"></div>' + '<div class="viewer-navbar">' + '<ul class="viewer-list"></ul>' + '</div>' + '</div>' + '<div class="viewer-tooltip"></div>' + '<div role="button" class="viewer-button" data-viewer-action="mix"></div>' + '<div class="viewer-player"></div>' + '</div>';
var IN_BROWSER = typeof window !== 'undefined';
var WINDOW = IN_BROWSER ? window : {};
var NAMESPACE = 'viewer'; // Actions
var ACTION_MOVE = 'move';
var ACTION_SWITCH = 'switch';
var ACTION_ZOOM = 'zoom'; // Classes
var CLASS_ACTIVE = "".concat(NAMESPACE, "-active");
var CLASS_CLOSE = "".concat(NAMESPACE, "-close");
var CLASS_FADE = "".concat(NAMESPACE, "-fade");
var CLASS_FIXED = "".concat(NAMESPACE, "-fixed");
var CLASS_FULLSCREEN = "".concat(NAMESPACE, "-fullscreen");
var CLASS_FULLSCREEN_EXIT = "".concat(NAMESPACE, "-fullscreen-exit");
var CLASS_HIDE = "".concat(NAMESPACE, "-hide");
var CLASS_HIDE_MD_DOWN = "".concat(NAMESPACE, "-hide-md-down");
var CLASS_HIDE_SM_DOWN = "".concat(NAMESPACE, "-hide-sm-down");
var CLASS_HIDE_XS_DOWN = "".concat(NAMESPACE, "-hide-xs-down");
var CLASS_IN = "".concat(NAMESPACE, "-in");
var CLASS_INVISIBLE = "".concat(NAMESPACE, "-invisible");
var CLASS_LOADING = "".concat(NAMESPACE, "-loading");
var CLASS_MOVE = "".concat(NAMESPACE, "-move");
var CLASS_OPEN = "".concat(NAMESPACE, "-open");
var CLASS_SHOW = "".concat(NAMESPACE, "-show");
var CLASS_TRANSITION = "".concat(NAMESPACE, "-transition"); // Events
var EVENT_CLICK = 'click';
var EVENT_DBLCLICK = 'dblclick';
var EVENT_DRAG_START = 'dragstart';
var EVENT_HIDDEN = 'hidden';
var EVENT_HIDE = 'hide';
var EVENT_KEY_DOWN = 'keydown';
var EVENT_LOAD = 'load';
var EVENT_POINTER_DOWN = WINDOW.PointerEvent ? 'pointerdown' : 'touchstart mousedown';
var EVENT_POINTER_MOVE = WINDOW.PointerEvent ? 'pointermove' : 'touchmove mousemove';
var EVENT_POINTER_UP = WINDOW.PointerEvent ? 'pointerup pointercancel' : 'touchend touchcancel mouseup';
var EVENT_READY = 'ready';
var EVENT_RESIZE = 'resize';
var EVENT_SHOW = 'show';
var EVENT_SHOWN = 'shown';
var EVENT_TRANSITION_END = 'transitionend';
var EVENT_VIEW = 'view';
var EVENT_VIEWED = 'viewed';
var EVENT_WHEEL = 'wheel mousewheel DOMMouseScroll';
var EVENT_ZOOM = 'zoom';
var EVENT_ZOOMED = 'zoomed'; // Data keys
var DATA_ACTION = "".concat(NAMESPACE, "Action");
var BUTTONS = ['zoom-in', 'zoom-out', 'one-to-one', 'reset', 'prev', 'play', 'next', 'rotate-left', 'rotate-right', 'flip-horizontal', 'flip-vertical']; // RegExps
var REGEXP_SPACES = /\s\s*/;
/**
* Check if the given value is a string.
* @param {*} value - The value to check.
* @returns {boolean} Returns `true` if the given value is a string, else `false`.
*/
function isString(value) {
return typeof value === 'string';
}
/**
* Check if the given value is not a number.
*/
var isNaN = Number.isNaN || WINDOW.isNaN;
/**
* Check if the given value is a number.
* @param {*} value - The value to check.
* @returns {boolean} Returns `true` if the given value is a number, else `false`.
*/
function isNumber(value) {
return typeof value === 'number' && !isNaN(value);
}
/**
* Check if the given value is undefined.
* @param {*} value - The value to check.
* @returns {boolean} Returns `true` if the given value is undefined, else `false`.
*/
function isUndefined(value) {
return typeof value === 'undefined';
}
/**
* Check if the given value is an object.
* @param {*} value - The value to check.
* @returns {boolean} Returns `true` if the given value is an object, else `false`.
*/
function isObject(value) {
return _typeof(value) === 'object' && value !== null;
}
var hasOwnProperty = Object.prototype.hasOwnProperty;
/**
* Check if the given value is a plain object.
* @param {*} value - The value to check.
* @returns {boolean} Returns `true` if the given value is a plain object, else `false`.
*/
function isPlainObject(value) {
if (!isObject(value)) {
return false;
}
try {
var _constructor = value.constructor;
var prototype = _constructor.prototype;
return _constructor && prototype && hasOwnProperty.call(prototype, 'isPrototypeOf');
} catch (e) {
return false;
}
}
/**
* Check if the given value is a function.
* @param {*} value - The value to check.
* @returns {boolean} Returns `true` if the given value is a function, else `false`.
*/
function isFunction(value) {
return typeof value === 'function';
}
/**
* Iterate the given data.
* @param {*} data - The data to iterate.
* @param {Function} callback - The process function for each element.
* @returns {*} The original data.
*/
function forEach(data, callback) {
if (data && isFunction(callback)) {
if (Array.isArray(data) || isNumber(data.length)
/* array-like */
) {
var length = data.length;
var i;
for (i = 0; i < length; i += 1) {
if (callback.call(data, data[i], i, data) === false) {
break;
}
}
} else if (isObject(data)) {
Object.keys(data).forEach(function (key) {
callback.call(data, data[key], key, data);
});
}
}
return data;
}
/**
* Extend the given object.
* @param {*} obj - The object to be extended.
* @param {*} args - The rest objects which will be merged to the first object.
* @returns {Object} The extended object.
*/
var assign = Object.assign || function assign(obj) {
for (var _len = arguments.length, args = new Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {
args[_key - 1] = arguments[_key];
}
if (isObject(obj) && args.length > 0) {
args.forEach(function (arg) {
if (isObject(arg)) {
Object.keys(arg).forEach(function (key) {
obj[key] = arg[key];
});
}
});
}
return obj;
};
var REGEXP_SUFFIX = /^(?:width|height|left|top|marginLeft|marginTop)$/;
/**
* Apply styles to the given element.
* @param {Element} element - The target element.
* @param {Object} styles - The styles for applying.
*/
function setStyle(element, styles) {
var style = element.style;
forEach(styles, function (value, property) {
if (REGEXP_SUFFIX.test(property) && isNumber(value)) {
value += 'px';
}
style[property] = value;
});
}
/**
* Check if the given element has a special class.
* @param {Element} element - The element to check.
* @param {string} value - The class to search.
* @returns {boolean} Returns `true` if the special class was found.
*/
function hasClass(element, value) {
return element.classList ? element.classList.contains(value) : element.className.indexOf(value) > -1;
}
/**
* Add classes to the given element.
* @param {Element} element - The target element.
* @param {string} value - The classes to be added.
*/
function addClass(element, value) {
if (!value) {
return;
}
if (isNumber(element.length)) {
forEach(element, function (elem) {
addClass(elem, value);
});
return;
}
if (element.classList) {
element.classList.add(value);
return;
}
var className = element.className.trim();
if (!className) {
element.className = value;
} else if (className.indexOf(value) < 0) {
element.className = "".concat(className, " ").concat(value);
}
}
/**
* Remove classes from the given element.
* @param {Element} element - The target element.
* @param {string} value - The classes to be removed.
*/
function removeClass(element, value) {
if (!value) {
return;
}
if (isNumber(element.length)) {
forEach(element, function (elem) {
removeClass(elem, value);
});
return;
}
if (element.classList) {
element.classList.remove(value);
return;
}
if (element.className.indexOf(value) >= 0) {
element.className = element.className.replace(value, '');
}
}
/**
* Add or remove classes from the given element.
* @param {Element} element - The target element.
* @param {string} value - The classes to be toggled.
* @param {boolean} added - Add only.
*/
function toggleClass(element, value, added) {
if (!value) {
return;
}
if (isNumber(element.length)) {
forEach(element, function (elem) {
toggleClass(elem, value, added);
});
return;
} // IE10-11 doesn't support the second parameter of `classList.toggle`
if (added) {
addClass(element, value);
} else {
removeClass(element, value);
}
}
var REGEXP_HYPHENATE = /([a-z\d])([A-Z])/g;
/**
* Transform the given string from camelCase to kebab-case
* @param {string} value - The value to transform.
* @returns {string} The transformed value.
*/
function hyphenate(value) {
return value.replace(REGEXP_HYPHENATE, '$1-$2').toLowerCase();
}
/**
* Get data from the given element.
* @param {Element} element - The target element.
* @param {string} name - The data key to get.
* @returns {string} The data value.
*/
function getData(element, name) {
if (isObject(element[name])) {
return element[name];
}
if (element.dataset) {
return element.dataset[name];
}
return element.getAttribute("data-".concat(hyphenate(name)));
}
/**
* Set data to the given element.
* @param {Element} element - The target element.
* @param {string} name - The data key to set.
* @param {string} data - The data value.
*/
function setData(element, name, data) {
if (isObject(data)) {
element[name] = data;
} else if (element.dataset) {
element.dataset[name] = data;
} else {
element.setAttribute("data-".concat(hyphenate(name)), data);
}
}
var onceSupported = function () {
var supported = false;
if (IN_BROWSER) {
var once = false;
var listener = function listener() {};
var options = Object.defineProperty({}, 'once', {
get: function get() {
supported = true;
return once;
},
/**
* This setter can fix a `TypeError` in strict mode
* {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Errors/Getter_only}
* @param {boolean} value - The value to set
*/
set: function set(value) {
once = value;
}
});
WINDOW.addEventListener('test', listener, options);
WINDOW.removeEventListener('test', listener, options);
}
return supported;
}();
/**
* Remove event listener from the target element.
* @param {Element} element - The event target.
* @param {string} type - The event type(s).
* @param {Function} listener - The event listener.
* @param {Object} options - The event options.
*/
function removeListener(element, type, listener) {
var options = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : {};
var handler = listener;
type.trim().split(REGEXP_SPACES).forEach(function (event) {
if (!onceSupported) {
var listeners = element.listeners;
if (listeners && listeners[event] && listeners[event][listener]) {
handler = listeners[event][listener];
delete listeners[event][listener];
if (Object.keys(listeners[event]).length === 0) {
delete listeners[event];
}
if (Object.keys(listeners).length === 0) {
delete element.listeners;
}
}
}
element.removeEventListener(event, handler, options);
});
}
/**
* Add event listener to the target element.
* @param {Element} element - The event target.
* @param {string} type - The event type(s).
* @param {Function} listener - The event listener.
* @param {Object} options - The event options.
*/
function addListener(element, type, listener) {
var options = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : {};
var _handler = listener;
type.trim().split(REGEXP_SPACES).forEach(function (event) {
if (options.once && !onceSupported) {
var _element$listeners = element.listeners,
listeners = _element$listeners === void 0 ? {} : _element$listeners;
_handler = function handler() {
delete listeners[event][listener];
element.removeEventListener(event, _handler, options);
for (var _len2 = arguments.length, args = new Array(_len2), _key2 = 0; _key2 < _len2; _key2++) {
args[_key2] = arguments[_key2];
}
listener.apply(element, args);
};
if (!listeners[event]) {
listeners[event] = {};
}
if (listeners[event][listener]) {
element.removeEventListener(event, listeners[event][listener], options);
}
listeners[event][listener] = _handler;
element.listeners = listeners;
}
element.addEventListener(event, _handler, options);
});
}
/**
* Dispatch event on the target element.
* @param {Element} element - The event target.
* @param {string} type - The event type(s).
* @param {Object} data - The additional event data.
* @returns {boolean} Indicate if the event is default prevented or not.
*/
function dispatchEvent(element, type, data) {
var event; // Event and CustomEvent on IE9-11 are global objects, not constructors
if (isFunction(Event) && isFunction(CustomEvent)) {
event = new CustomEvent(type, {
detail: data,
bubbles: true,
cancelable: true
});
} else {
event = document.createEvent('CustomEvent');
event.initCustomEvent(type, true, true, data);
}
return element.dispatchEvent(event);
}
/**
* Get the offset base on the document.
* @param {Element} element - The target element.
* @returns {Object} The offset data.
*/
function getOffset(element) {
var box = element.getBoundingClientRect();
return {
left: box.left + (window.pageXOffset - document.documentElement.clientLeft),
top: box.top + (window.pageYOffset - document.documentElement.clientTop)
};
}
/**
* Get transforms base on the given object.
* @param {Object} obj - The target object.
* @returns {string} A string contains transform values.
*/
function getTransforms(_ref) {
var rotate = _ref.rotate,
scaleX = _ref.scaleX,
scaleY = _ref.scaleY,
translateX = _ref.translateX,
translateY = _ref.translateY;
var values = [];
if (isNumber(translateX) && translateX !== 0) {
values.push("translateX(".concat(translateX, "px)"));
}
if (isNumber(translateY) && translateY !== 0) {
values.push("translateY(".concat(translateY, "px)"));
} // Rotate should come first before scale to match orientation transform
if (isNumber(rotate) && rotate !== 0) {
values.push("rotate(".concat(rotate, "deg)"));
}
if (isNumber(scaleX) && scaleX !== 1) {
values.push("scaleX(".concat(scaleX, ")"));
}
if (isNumber(scaleY) && scaleY !== 1) {
values.push("scaleY(".concat(scaleY, ")"));
}
var transform = values.length ? values.join(' ') : 'none';
return {
WebkitTransform: transform,
msTransform: transform,
transform: transform
};
}
/**
* Get an image name from an image url.
* @param {string} url - The target url.
* @example
* // picture.jpg
* getImageNameFromURL('http://domain.com/path/to/picture.jpg?size=1280×960')
* @returns {string} A string contains the image name.
*/
function getImageNameFromURL(url) {
return isString(url) ? url.replace(/^.*\//, '').replace(/[?&#].*$/, '') : '';
}
var IS_SAFARI = WINDOW.navigator && /(Macintosh|iPhone|iPod|iPad).*AppleWebKit/i.test(WINDOW.navigator.userAgent);
/**
* Get an image's natural sizes.
* @param {string} image - The target image.
* @param {Function} callback - The callback function.
* @returns {HTMLImageElement} The new image.
*/
function getImageNaturalSizes(image, callback) {
var newImage = document.createElement('img'); // Modern browsers (except Safari)
if (image.naturalWidth && !IS_SAFARI) {
callback(image.naturalWidth, image.naturalHeight);
return newImage;
}
var body = document.body || document.documentElement;
newImage.onload = function () {
callback(newImage.width, newImage.height);
if (!IS_SAFARI) {
body.removeChild(newImage);
}
};
newImage.src = image.src; // iOS Safari will convert the image automatically
// with its orientation once append it into DOM
if (!IS_SAFARI) {
newImage.style.cssText = 'left:0;' + 'max-height:none!important;' + 'max-width:none!important;' + 'min-height:0!important;' + 'min-width:0!important;' + 'opacity:0;' + 'position:absolute;' + 'top:0;' + 'z-index:-1;';
body.appendChild(newImage);
}
return newImage;
}
/**
* Get the related class name of a responsive type number.
* @param {string} type - The responsive type.
* @returns {string} The related class name.
*/
function getResponsiveClass(type) {
switch (type) {
case 2:
return CLASS_HIDE_XS_DOWN;
case 3:
return CLASS_HIDE_SM_DOWN;
case 4:
return CLASS_HIDE_MD_DOWN;
default:
return '';
}
}
/**
* Get the max ratio of a group of pointers.
* @param {string} pointers - The target pointers.
* @returns {number} The result ratio.
*/
function getMaxZoomRatio(pointers) {
var pointers2 = assign({}, pointers);
var ratios = [];
forEach(pointers, function (pointer, pointerId) {
delete pointers2[pointerId];
forEach(pointers2, function (pointer2) {
var x1 = Math.abs(pointer.startX - pointer2.startX);
var y1 = Math.abs(pointer.startY - pointer2.startY);
var x2 = Math.abs(pointer.endX - pointer2.endX);
var y2 = Math.abs(pointer.endY - pointer2.endY);
var z1 = Math.sqrt(x1 * x1 + y1 * y1);
var z2 = Math.sqrt(x2 * x2 + y2 * y2);
var ratio = (z2 - z1) / z1;
ratios.push(ratio);
});
});
ratios.sort(function (a, b) {
return Math.abs(a) < Math.abs(b);
});
return ratios[0];
}
/**
* Get a pointer from an event object.
* @param {Object} event - The target event object.
* @param {boolean} endOnly - Indicates if only returns the end point coordinate or not.
* @returns {Object} The result pointer contains start and/or end point coordinates.
*/
function getPointer(_ref2, endOnly) {
var pageX = _ref2.pageX,
pageY = _ref2.pageY;
var end = {
endX: pageX,
endY: pageY
};
return endOnly ? end : assign({
startX: pageX,
startY: pageY
}, end);
}
/**
* Get the center point coordinate of a group of pointers.
* @param {Object} pointers - The target pointers.
* @returns {Object} The center point coordinate.
*/
function getPointersCenter(pointers) {
var pageX = 0;
var pageY = 0;
var count = 0;
forEach(pointers, function (_ref3) {
var startX = _ref3.startX,
startY = _ref3.startY;
pageX += startX;
pageY += startY;
count += 1;
});
pageX /= count;
pageY /= count;
return {
pageX: pageX,
pageY: pageY
};
}
var render = {
render: function render() {
this.initContainer();
this.initViewer();
this.initList();
this.renderViewer();
},
initContainer: function initContainer() {
this.containerData = {
width: window.innerWidth,
height: window.innerHeight
};
},
initViewer: function initViewer() {
var options = this.options,
parent = this.parent;
var viewerData;
if (options.inline) {
viewerData = {
width: Math.max(parent.offsetWidth, options.minWidth),
height: Math.max(parent.offsetHeight, options.minHeight)
};
this.parentData = viewerData;
}
if (this.fulled || !viewerData) {
viewerData = this.containerData;
}
this.viewerData = assign({}, viewerData);
},
renderViewer: function renderViewer() {
if (this.options.inline && !this.fulled) {
setStyle(this.viewer, this.viewerData);
}
},
initList: function initList() {
var _this = this;
var element = this.element,
options = this.options,
list = this.list;
var items = [];
forEach(this.images, function (image, i) {
var src = image.src;
var alt = image.alt || getImageNameFromURL(src);
var url = options.url;
if (isString(url)) {
url = image.getAttribute(url);
} else if (isFunction(url)) {
url = url.call(_this, image);
}
if (src || url) {
items.push('<li>' + '<img' + " src=\"".concat(src || url, "\"") + ' role="button"' + ' data-viewer-action="view"' + " data-index=\"".concat(i, "\"") + " data-original-url=\"".concat(url || src, "\"") + " alt=\"".concat(alt, "\"") + '>' + '</li>');
}
});
list.innerHTML = items.join('');
this.items = list.getElementsByTagName('li');
forEach(this.items, function (item) {
var image = item.firstElementChild;
setData(image, 'filled', true);
if (options.loading) {
addClass(item, CLASS_LOADING);
}
addListener(image, EVENT_LOAD, function (event) {
if (options.loading) {
removeClass(item, CLASS_LOADING);
}
_this.loadImage(event);
}, {
once: true
});
});
if (options.transition) {
addListener(element, EVENT_VIEWED, function () {
addClass(list, CLASS_TRANSITION);
}, {
once: true
});
}
},
renderList: function renderList(index) {
var i = index || this.index;
var width = this.items[i].offsetWidth || 30;
var outerWidth = width + 1; // 1 pixel of `margin-left` width
// Place the active item in the center of the screen
setStyle(this.list, assign({
width: outerWidth * this.length
}, getTransforms({
translateX: (this.viewerData.width - width) / 2 - outerWidth * i
})));
},
resetList: function resetList() {
var list = this.list;
list.innerHTML = '';
removeClass(list, CLASS_TRANSITION);
setStyle(list, getTransforms({
translateX: 0
}));
},
initImage: function initImage(done) {
var _this2 = this;
var options = this.options,
image = this.image,
viewerData = this.viewerData;
var footerHeight = this.footer.offsetHeight;
var viewerWidth = viewerData.width;
var viewerHeight = Math.max(viewerData.height - footerHeight, footerHeight);
var oldImageData = this.imageData || {};
var sizingImage;
this.imageInitializing = {
abort: function abort() {
sizingImage.onload = null;
}
};
sizingImage = getImageNaturalSizes(image, function (naturalWidth, naturalHeight) {
var aspectRatio = naturalWidth / naturalHeight;
var width = viewerWidth;
var height = viewerHeight;
_this2.imageInitializing = false;
if (viewerHeight * aspectRatio > viewerWidth) {
height = viewerWidth / aspectRatio;
} else {
width = viewerHeight * aspectRatio;
}
width = Math.min(width * 0.9, naturalWidth);
height = Math.min(height * 0.9, naturalHeight);
var imageData = {
naturalWidth: naturalWidth,
naturalHeight: naturalHeight,
aspectRatio: aspectRatio,
ratio: width / naturalWidth,
width: width,
height: height,
left: (viewerWidth - width) / 2,
top: (viewerHeight - height) / 2
};
var initialImageData = assign({}, imageData);
if (options.rotatable) {
imageData.rotate = oldImageData.rotate || 0;
initialImageData.rotate = 0;
}
if (options.scalable) {
imageData.scaleX = oldImageData.scaleX || 1;
imageData.scaleY = oldImageData.scaleY || 1;
initialImageData.scaleX = 1;
initialImageData.scaleY = 1;
}
_this2.imageData = imageData;
_this2.initialImageData = initialImageData;
if (done) {
done();
}
});
},
renderImage: function renderImage(done) {
var _this3 = this;
var image = this.image,
imageData = this.imageData;
setStyle(image, assign({
width: imageData.width,
height: imageData.height,
marginLeft: imageData.left,
marginTop: imageData.top
}, getTransforms(imageData)));
if (done) {
if ((this.viewing || this.zooming) && this.options.transition) {
var onTransitionEnd = function onTransitionEnd() {
_this3.imageRendering = false;
done();
};
this.imageRendering = {
abort: function abort() {
removeListener(image, EVENT_TRANSITION_END, onTransitionEnd);
}
};
addListener(image, EVENT_TRANSITION_END, onTransitionEnd, {
once: true
});
} else {
done();
}
}
},
resetImage: function resetImage() {
// this.image only defined after viewed
if (this.viewing || this.viewed) {
var image = this.image;
if (this.viewing) {
this.viewing.abort();
}
image.parentNode.removeChild(image);
this.image = null;
}
}
};
var events = {
bind: function bind() {
var canvas = this.canvas,
element = this.element,
viewer = this.viewer;
addListener(viewer, EVENT_CLICK, this.onClick = this.click.bind(this));
addListener(viewer, EVENT_WHEEL, this.onWheel = this.wheel.bind(this));
addListener(viewer, EVENT_DRAG_START, this.onDragStart = this.dragstart.bind(this));
if (this.options.toggleOnDblclick) {
addListener(canvas, EVENT_DBLCLICK, this.onDblclick = this.dblclick.bind(this));
}
addListener(canvas, EVENT_POINTER_DOWN, this.onPointerDown = this.pointerdown.bind(this));
addListener(element.ownerDocument, EVENT_POINTER_MOVE, this.onPointerMove = this.pointermove.bind(this));
addListener(element.ownerDocument, EVENT_POINTER_UP, this.onPointerUp = this.pointerup.bind(this));
addListener(element.ownerDocument, EVENT_KEY_DOWN, this.onKeyDown = this.keydown.bind(this));
addListener(window, EVENT_RESIZE, this.onResize = this.resize.bind(this));
},
unbind: function unbind() {
var canvas = this.canvas,
element = this.element,
viewer = this.viewer;
removeListener(viewer, EVENT_CLICK, this.onClick);
removeListener(viewer, EVENT_WHEEL, this.onWheel);
removeListener(viewer, EVENT_DRAG_START, this.onDragStart);
if (this.options.toggleOnDblclick) {
removeListener(canvas, EVENT_DBLCLICK, this.onDblclick);
}
removeListener(canvas, EVENT_POINTER_DOWN, this.onPointerDown);
removeListener(element.ownerDocument, EVENT_POINTER_MOVE, this.onPointerMove);
removeListener(element.ownerDocument, EVENT_POINTER_UP, this.onPointerUp);
removeListener(element.ownerDocument, EVENT_KEY_DOWN, this.onKeyDown);
removeListener(window, EVENT_RESIZE, this.onResize);
}
};
var handlers = {
click: function click(_ref) {
var target = _ref.target;
var options = this.options,
imageData = this.imageData;
var action = getData(target, DATA_ACTION);
switch (action) {
case 'mix':
if (this.played) {
this.stop();
} else if (options.inline) {
if (this.fulled) {
this.exit();
} else {
this.full();
}
} else {
this.hide();
}
break;
case 'hide':
this.hide();
break;
case 'view':
this.view(getData(target, 'index'));
break;
case 'zoom-in':
this.zoom(0.1, true);
break;
case 'zoom-out':
this.zoom(-0.1, true);
break;
case 'one-to-one':
this.toggle();
break;
case 'reset':
this.reset();
break;
case 'prev':
this.prev(options.loop);
break;
case 'play':
this.play(options.fullscreen);
break;
case 'next':
this.next(options.loop);
break;
case 'rotate-left':
this.rotate(-90);
break;
case 'rotate-right':
this.rotate(90);
break;
case 'flip-horizontal':
this.scaleX(-imageData.scaleX || -1);
break;
case 'flip-vertical':
this.scaleY(-imageData.scaleY || -1);
break;
default:
if (this.played) {
this.stop();
}
}
},
dblclick: function dblclick(event) {
if (event.target.parentElement === this.canvas) {
this.toggle();
}
},
load: function load() {
var _this = this;
if (this.timeout) {
clearTimeout(this.timeout);
this.timeout = false;
}
var element = this.element,
options = this.options,
image = this.image,
index = this.index,
viewerData = this.viewerData;
removeClass(image, CLASS_INVISIBLE);
if (options.loading) {
removeClass(this.canvas, CLASS_LOADING);
}
image.style.cssText = 'height:0;' + "margin-left:".concat(viewerData.width / 2, "px;") + "margin-top:".concat(viewerData.height / 2, "px;") + 'max-width:none!important;' + 'position:absolute;' + 'width:0;';
this.initImage(function () {
toggleClass(image, CLASS_MOVE, options.movable);
toggleClass(image, CLASS_TRANSITION, options.transition);
_this.renderImage(function () {
_this.viewed = true;
_this.viewing = false;
if (isFunction(options.viewed)) {
addListener(element, EVENT_VIEWED, options.viewed, {
once: true
});
}
dispatchEvent(element, EVENT_VIEWED, {
originalImage: _this.images[index],
index: index,
image: image
});
});
});
},
loadImage: function loadImage(e) {
var image = e.target;
var parent = image.parentNode;
var parentWidth = parent.offsetWidth || 30;
var parentHeight = parent.offsetHeight || 50;
var filled = !!getData(image, 'filled');
getImageNaturalSizes(image, function (naturalWidth, naturalHeight) {
var aspectRatio = naturalWidth / naturalHeight;
var width = parentWidth;
var height = parentHeight;
if (parentHeight * aspectRatio > parentWidth) {
if (filled) {
width = parentHeight * aspectRatio;
} else {
height = parentWidth / aspectRatio;
}
} else if (filled) {
height = parentWidth / aspectRatio;
} else {
width = parentHeight * aspectRatio;
}
setStyle(image, assign({
width: width,
height: height
}, getTransforms({
translateX: (parentWidth - width) / 2,
translateY: (parentHeight - height) / 2
})));
});
},
keydown: function keydown(e) {
var options = this.options;
if (!this.fulled || !options.keyboard) {
return;
}
switch (e.keyCode || e.which || e.charCode) {
// Escape
case 27:
if (this.played) {
this.stop();
} else if (options.inline) {
if (this.fulled) {
this.exit();
}
} else {
this.hide();
}
break;
// Space
case 32:
if (this.played) {
this.stop();
}
break;
// ArrowLeft
case 37:
this.prev(options.loop);
break;
// ArrowUp
case 38:
// Prevent scroll on Firefox
e.preventDefault(); // Zoom in
this.zoom(options.zoomRatio, true);
break;
// ArrowRight
case 39:
this.next(options.loop);
break;
// ArrowDown
case 40:
// Prevent scroll on Firefox
e.preventDefault(); // Zoom out
this.zoom(-options.zoomRatio, true);
break;
// Ctrl + 0
case 48: // Fall through
// Ctrl + 1
// eslint-disable-next-line no-fallthrough
case 49:
if (e.ctrlKey) {
e.preventDefault();
this.toggle();
}
break;
default:
}
},
dragstart: function dragstart(e) {
if (e.target.tagName.toLowerCase() === 'img') {
e.preventDefault();
}
},
pointerdown: function pointerdown(e) {
var options = this.options,
pointers = this.pointers;
if (!this.viewed || this.showing || this.viewing || this.hiding) {
return;
} // This line is required for preventing page zooming in iOS browsers
e.preventDefault();
if (e.changedTouches) {
forEach(e.changedTouches, function (touch) {
pointers[touch.identifier] = getPointer(touch);
});
} else {
pointers[e.pointerId || 0] = getPointer(e);
}
var action = options.movable ? ACTION_MOVE : false;
if (Object.keys(pointers).length > 1) {
action = ACTION_ZOOM;
} else if ((e.pointerType === 'touch' || e.type === 'touchstart') && this.isSwitchable()) {
action = ACTION_SWITCH;
}
if (options.transition && (action === ACTION_MOVE || action === ACTION_ZOOM)) {
removeClass(this.image, CLASS_TRANSITION);
}
this.action = action;
},
pointermove: function pointermove(e) {
var pointers = this.pointers,
action = this.action;
if (!this.viewed || !action) {
return;
}
e.preventDefault();
if (e.changedTouches) {
forEach(e.changedTouches, function (touch) {
// // The first parameter should not be undefined in some browsers
assign(pointers[touch.identifier] || {}, getPointer(touch, true));
});
} else {
assign(pointers[e.pointerId || 0] || {}, getPointer(e, true));
}
this.change(e);
},
pointerup: function pointerup(e) {
var action = this.action,
pointers = this.pointers;
if (e.changedTouches) {
forEach(e.changedTouches, function (touch) {
delete pointers[touch.identifier];
});
} else {
delete pointers[e.pointerId || 0];
}
if (!action) {
return;
}
e.preventDefault();
if (this.options.transition && (action === ACTION_MOVE || action === ACTION_ZOOM)) {
addClass(this.image, CLASS_TRANSITION);
}
this.action = false;
},
resize: function resize() {
var _this2 = this;
if (!this.isShown || this.hiding) {
return;
}
this.initContainer();
this.initViewer();
this.renderViewer();
this.renderList();
if (this.viewed) {
this.initImage(function () {
_this2.renderImage();
});
}
if (this.played) {
if (this.options.fullscreen && this.fulled && !document.fullscreenElement && !document.mozFullScreenElement && !document.webkitFullscreenElement && !document.msFullscreenElement) {
this.stop();
return;
}
forEach(this.player.getElementsByTagName('img'), function (image) {
addListener(image, EVENT_LOAD, _this2.loadImage.bind(_this2), {
once: true
});
dispatchEvent(image, EVENT_LOAD);
});
}
},
wheel: function wheel(e) {
var _this3 = this;
if (!this.viewed) {
return;
}
e.preventDefault(); // Limit wheel speed to prevent zoom too fast
if (this.wheeling) {
return;
}
this.wheeling = true;
setTimeout(function () {
_this3.wheeling = false;
}, 50);
var ratio = Number(this.options.zoomRatio) || 0.1;
var delta = 1;
if (e.deltaY) {
delta = e.deltaY > 0 ? 1 : -1;
} else if (e.wheelDelta) {
delta = -e.wheelDelta / 120;
} else if (e.detail) {
delta = e.detail > 0 ? 1 : -1;
}
this.zoom(-delta * ratio, true, e);
}
};
var methods = {
/** Show the viewer (only available in modal mode)
* @param {boolean} [immediate=false] - Indicates if show the viewer immediately or not.
* @returns {Viewer} this
*/
show: function show() {
var immediate = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : false;
var element = this.element,
options = this.options;
if (options.inline || this.showing || this.isShown || this.showing) {
return this;
}
if (!this.ready) {
this.build();
if (this.ready) {
this.show(immediate);
}
return this;
}
if (isFunction(options.show)) {
addListener(element, EVENT_SHOW, options.show, {
once: true
});
}
if (dispatchEvent(element, EVENT_SHOW) === false || !this.ready) {
return this;
}
if (this.hiding) {
this.transitioning.abort();
}
this.showing = true;
this.open();
var viewer = this.viewer;
removeClass(viewer, CLASS_HIDE);
if (options.transition && !immediate) {
var shown = this.shown.bind(this);
this.transitioning = {
abort: function abort() {
removeListener(viewer, EVENT_TRANSITION_END, shown);
removeClass(viewer, CLASS_IN);
}
};
addClass(viewer, CLASS_TRANSITION); // Force reflow to enable CSS3 transition
// eslint-disable-next-line
viewer.offsetWidth;
addListener(viewer, EVENT_TRANSITION_END, shown, {
once: true
});
addClass(viewer, CLASS_IN);
} else {
addClass(viewer, CLASS_IN);
this.shown();
}
return this;
},
/**
* Hide the viewer (only available in modal mode)
* @param {boolean} [immediate=false] - Indicates if hide the viewer immediately or not.
* @returns {Viewer} this
*/
hide: function hide() {
var immediate = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : false;
var element = this.element,
options = this.options;
if (options.inline || this.hiding || !(this.isShown || this.showing)) {
return this;
}
if (isFunction(options.hide)) {
addListener(element, EVENT_HIDE, options.hide, {
once: true
});
}
if (dispatchEvent(element, EVENT_HIDE) === false) {
return this;
}
if (this.showing) {
this.transitioning.abort();
}
this.hiding = true;
if (this.played) {
this.stop();
} else if (this.viewing) {
this.viewing.abort();
}
var viewer = this.viewer;
if (options.transition && !immediate) {
var hidden = this.hidden.bind(this);
var hide = function hide() {
addListener(viewer, EVENT_TRANSITION_END, hidden, {
once: true
});
removeClass(viewer, CLASS_IN);
};
this.transitioning = {
abort: function abort() {
if (this.viewed) {
removeListener(this.image, EVENT_TRANSITION_END, hide);
} else {
removeListener(viewer, EVENT_TRANSITION_END, hidden);
}
}
};
if (this.viewed) {
addListener(this.image, EVENT_TRANSITION_END, hide, {
once: true
});
this.zoomTo(0, false, false, true);
} else {
hide();
}
} else {
removeClass(viewer, CLASS_IN);
this.hidden();
}
return this;
},
/**
* View one of the images with image's index
* @param {number} index - The index of the image to view.
* @returns {Viewer} this
*/
view: function view() {
var _this = this;
var index = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : this.options.initialViewIndex;
index = Number(index) || 0;
if (!this.isShown) {
this.index = index;
return this.show();
}
if (this.hiding || this.played || index < 0 || index >= this.length || this.viewed && index === this.index) {
return this;
}
if (this.viewing) {
this.viewing.abort();
}
var element = this.element,
options = this.options,
title = this.title,
canvas = this.canvas;
var item = this.items[index];
var img = item.querySelector('img');
var url = getData(img, 'originalUrl');
var alt = img.getAttribute('alt');
var image = document.createElement('img');
image.src = url;
image.alt = alt;
if (isFunction(options.view)) {
addListener(element, EVENT_VIEW, options.view, {
once: true
});
}
if (dispatchEvent(element, EVENT_VIEW, {
originalImage: this.images[index],
index: index,
image: image
}) === false || !this.isShown || this.hiding || this.played) {
return this;
}
this.image = image;
removeClass(this.items[this.index], CLASS_ACTIVE);
addClass(item, CLASS_ACTIVE);
this.viewed = false;
this.index = index;
this.imageData = {};
addClass(image, CLASS_INVISIBLE);
if (options.loading) {
addClass(canvas, CLASS_LOADING);
}
canvas.innerHTML = '';
canvas.appendChild(image); // Center current item
this.renderList(); // Clear title
title.innerHTML = ''; // Generate title after viewed
var onViewed = function onViewed() {
var imageData = _this.imageData;
var render = Array.isArray(options.title) ? options.title[1] : options.title;
title.innerHTML = isFunction(render) ? render.call(_this, image, imageData) : "".concat(alt, " (").concat(imageData.naturalWidth, " \xD7 ").concat(imageData.naturalHeight, ")");
};
var onLoad;
addListener(element, EVENT_VIEWED, onViewed, {
once: true
});
this.viewing = {
abort: function abort() {
removeListener(element, EVENT_VIEWED, onViewed);
if (image.complete) {
if (this.imageRendering) {
this.imageRendering.abort();
} else if (this.imageInitializing) {
this.imageInitializing.abort();
}
} else {
removeListener(image, EVENT_LOAD, onLoad);
if (this.timeout) {
clearTimeout(this.timeout);
}
}
}
};
if (image.complete) {
this.load();
} else {
addListener(image, EVENT_LOAD, onLoad = this.load.bind(this), {
once: true
});
if (this.timeout) {
clearTimeout(this.timeout);
} // Make the image visible if it fails to load within 1s
this.timeout = setTimeout(function () {
removeClass(image, CLASS_INVISIBLE);
_this.timeout = false;
}, 1000);
}
return this;
},
/**
* View the previous image
* @param {boolean} [loop=false] - Indicate if view the last one
* when it is the first one at present.
* @returns {Viewer} this
*/
prev: function prev() {
var loop = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : false;
var index = this.index - 1;
if (index < 0) {
index = loop ? this.length - 1 : 0;
}
this.view(index);
return this;
},
/**
* View the next image
* @param {boolean} [loop=false] - Indicate if view the first one
* when it is the last one at present.
* @returns {Viewer} this
*/
next: function next() {
var loop = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : false;
var maxIndex = this.length - 1;
var index = this.index + 1;
if (index > maxIndex) {
index = loop ? 0 : maxIndex;
}
this.view(index);
return this;
},
/**
* Move the image with relative offsets.
* @param {number} offsetX - The relative offset distance on the x-axis.
* @param {number} offsetY - The relative offset distance on the y-axis.
* @returns {Viewer} this
*/
move: function move(offsetX, offsetY) {
var imageData = this.imageData;
this.moveTo(isUndefined(offsetX) ? offsetX : imageData.left + Number(offsetX), isUndefined(offsetY) ? offsetY : imageData.top + Number(offsetY));
return this;
},
/**
* Move the image to an absolute point.
* @param {number} x - The x-axis coordinate.
* @param {number} [y=x] - The y-axis coordinate.
* @returns {Viewer} this
*/
moveTo: function moveTo(x) {
var y = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : x;
var imageData = this.imageData;
x = Number(x);
y = Number(y);
if (this.viewed && !this.played && this.options.movable) {
var changed = false;
if (isNumber(x)) {
imageData.left = x;
changed = true;
}
if (isNumber(y)) {
imageData.top = y;
changed = true;
}
if (changed) {
this.renderImage();
}
}
return this;
},
/**
* Zoom the image with a relative ratio.
* @param {number} ratio - The target ratio.
* @param {boolean} [hasTooltip=false] - Indicates if it has a tooltip or not.
* @param {Event} [_originalEvent=null] - The original event if any.
* @returns {Viewer} this
*/
zoom: function zoom(ratio) {
var hasTooltip = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;
var _originalEvent = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : null;
var imageData = this.imageData;
ratio = Number(ratio);
if (ratio < 0) {
ratio = 1 / (1 - ratio);
} else {
ratio = 1 + ratio;
}
this.zoomTo(imageData.width * ratio / imageData.naturalWidth, hasTooltip, _originalEvent);
return this;
},
/**
* Zoom the image to an absolute ratio.
* @param {number} ratio - The target ratio.
* @param {boolean} [hasTooltip=false] - Indicates if it has a tooltip or not.
* @param {Event} [_originalEvent=null] - The original event if any.
* @param {Event} [_zoomable=false] - Indicates if the current zoom is available or not.
* @returns {Viewer} this
*/
zoomTo: function zoomTo(ratio) {
var _this2 = this;
var hasTooltip = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;
var _originalEvent = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : null;
var _zoomable = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : false;
var element = this.element,
options = this.options,
pointers = this.pointers,
imageData = this.imageData;
ratio = Math.max(0, ratio);
if (isNumber(ratio) && this.viewed && !this.played && (_zoomable || options.zoomable)) {
if (!_zoomable) {
var minZoomRatio = Math.max(0.01, options.minZoomRatio);
var maxZoomRatio = Math.min(100, options.maxZoomRatio);
ratio = Math.min(Math.max(ratio, minZoomRatio), maxZoomRatio);
}
if (_originalEvent && ratio > 0.95 && ratio < 1.05) {
ratio = 1;
}
var newWidth = imageData.naturalWidth * ratio;
var newHeight = imageData.naturalHeight * ratio;
var oldRatio = imageData.width / imageData.naturalWidth;
if (isFunction(options.zoom)) {
addListener(element, EVENT_ZOOM, options.zoom, {
once: true
});
}
if (dispatchEvent(element, EVENT_ZOOM, {
ratio: ratio,
oldRatio: oldRatio,
originalEvent: _originalEvent
}) === false) {
return this;
}
this.zooming = true;
if (_originalEvent) {
var offset = getOffset(this.viewer);
var center = pointers && Object.keys(pointers).length ? getPointersCenter(pointers) : {
pageX: _originalEvent.pageX,
pageY: _originalEvent.pageY
}; // Zoom from the triggering point of the event
imageData.left -= (newWidth - imageData.width) * ((center.pageX - offset.left - imageData.left) / imageData.width);
imageData.top -= (newHeight - imageData.height) * ((center.pageY - offset.top - imageData.top) / imageData.height);
} else {
// Zoom from the center of the image
imageData.left -= (newWidth - imageData.width) / 2;
imageData.top -= (newHeight - imageData.height) / 2;
}
imageData.width = newWidth;
imageData.height = newHeight;
imageData.ratio = ratio;
this.renderImage(function () {
_this2.zooming = false;
if (isFunction(options.zoomed)) {
addListener(element, EVENT_ZOOMED, options.zoomed, {
once: true
});
}
dispatchEvent(element, EVENT_ZOOMED, {
ratio: ratio,
oldRatio: oldRatio,
originalEvent: _originalEvent
});
});
if (hasTooltip) {
this.tooltip();
}
}
return this;
},
/**
* Rotate the image with a relative degree.
* @param {number} degree - The rotate degree.
* @returns {Viewer} this
*/
rotate: function rotate(degree) {
this.rotateTo((this.imageData.rotate || 0) + Number(degree));
return this;
},
/**
* Rotate the image to an absolute degree.
* @param {number} degree - The rotate degree.
* @returns {Viewer} this
*/
rotateTo: function rotateTo(degree) {
var imageData = this.imageData;
degree = Number(degree);
if (isNumber(degree) && this.viewed && !this.played && this.options.rotatable) {
imageData.rotate = degree;
this.renderImage();
}
return this;
},
/**
* Scale the image on the x-axis.
* @param {number} scaleX - The scale ratio on the x-axis.
* @returns {Viewer} this
*/
scaleX: function scaleX(_scaleX) {
this.scale(_scaleX, this.imageData.scaleY);
return this;
},
/**
* Scale the image on the y-axis.
* @param {number} scaleY - The scale ratio on the y-axis.
* @returns {Viewer} this
*/
scaleY: function scaleY(_scaleY) {
this.scale(this.imageData.scaleX, _scaleY);
return this;
},
/**
* Scale the image.
* @param {number} scaleX - The scale ratio on the x-axis.
* @param {number} [scaleY=scaleX] - The scale ratio on the y-axis.
* @returns {Viewer} this
*/
scale: function scale(scaleX) {
var scaleY = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : scaleX;
var imageData = this.imageData;
scaleX = Number(scaleX);
scaleY = Number(scaleY);
if (this.viewed && !this.played && this.options.scalable) {
var changed = false;
if (isNumber(scaleX)) {
imageData.scaleX = scaleX;
changed = true;
}
if (isNumber(scaleY)) {
imageData.scaleY = scaleY;
changed = true;
}
if (changed) {
this.renderImage();
}
}
return this;
},
/**
* Play the images
* @param {boolean} [fullscreen=false] - Indicate if request fullscreen or not.
* @returns {Viewer} this
*/
play: function play() {
var _this3 = this;
var fullscreen = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : false;
if (!this.isShown || this.played) {
return this;
}
var options = this.options,
player = this.player;
var onLoad = this.loadImage.bind(this);
var list = [];
var total = 0;
var index = 0;
this.played = true;
this.onLoadWhenPlay = onLoad;
if (fullscreen) {
this.requestFullscreen();
}
addClass(player, CLASS_SHOW);
forEach(this.items, function (item, i) {
var img = item.querySelector('img');
var image = document.createElement('img');
image.src = getData(img, 'originalUrl');
image.alt = img.getAttribute('alt');
total += 1;
addClass(image, CLASS_FADE);
toggleClass(image, CLASS_TRANSITION, options.transition);
if (hasClass(item, CLASS_ACTIVE)) {
addClass(image, CLASS_IN);
index = i;
}
list.push(image);
addListener(image, EVENT_LOAD, onLoad, {
once: true
});
player.appendChild(image);
});
if (isNumber(options.interval) && options.interval > 0) {
var play = function play() {
_this3.playing = setTimeout(function () {
removeClass(list[index], CLASS_IN);
index += 1;
index = index < total ? index : 0;
addClass(list[index], CLASS_IN);
play();
}, options.interval);
};
if (total > 1) {
play();
}
}
return this;
},
// Stop play
stop: function stop() {
var _this4 = this;
if (!this.played) {
return this;
}
var player = this.player;
this.played = false;
clearTimeout(this.playing);
forEach(player.getElementsByTagName('img'), function (image) {
removeListener(image, EVENT_LOAD, _this4.onLoadWhenPlay);
});
removeClass(player, CLASS_SHOW);
player.innerHTML = '';
this.exitFullscreen();
return this;
},
// Enter modal mode (only available in inline mode)
full: function full() {
var _this5 = this;
var options = this.options,
viewer = this.viewer,
image = this.image,
list = this.list;
if (!this.isShown || this.played || this.fulled || !options.inline) {
return this;
}
this.fulled = true;
this.open();
addClass(this.button, CLASS_FULLSCREEN_EXIT);
if (options.transition) {
removeClass(list, CLASS_TRANSITION);
if (this.viewed) {
removeClass(image, CLASS_TRANSITION);
}
}
addClass(viewer, CLASS_FIXED);
viewer.setAttribute('style', '');
setStyle(viewer, {
zIndex: options.zIndex
});
this.initContainer();
this.viewerData = assign({}, this.containerData);
this.renderList();
if (this.viewed) {
this.initImage(function () {
_this5.renderImage(function () {
if (options.transition) {
setTimeout(function () {
addClass(image, CLASS_TRANSITION);
addClass(list, CLASS_TRANSITION);
}, 0);
}
});
});
}
return this;
},
// Exit modal mode (only available in inline mode)
exit: function exit() {
var _this6 = this;
var options = this.options,
viewer = this.viewer,
image = this.image,
list = this.list;
if (!this.isShown || this.played || !this.fulled || !options.inline) {
return this;
}
this.fulled = false;
this.close();
removeClass(this.button, CLASS_FULLSCREEN_EXIT);
if (options.transition) {
removeClass(list, CLASS_TRANSITION);
if (this.viewed) {
removeClass(image, CLASS_TRANSITION);
}
}
removeClass(viewer, CLASS_FIXED);
setStyle(viewer, {
zIndex: options.zIndexInline
});
this.viewerData = assign({}, this.parentData);
this.renderViewer();
this.renderList();
if (this.viewed) {
this.initImage(function () {
_this6.renderImage(function () {
if (options.transition) {
setTimeout(function () {
addClass(image, CLASS_TRANSITION);
addClass(list, CLASS_TRANSITION);
}, 0);
}
});
});
}
return this;
},
// Show the current ratio of the image with percentage
tooltip: function tooltip() {
var _this7 = this;
var options = this.options,
tooltipBox = this.tooltipBox,
imageData = this.imageData;
if (!this.viewed || this.played || !options.tooltip) {
return this;
}
tooltipBox.textContent = "".concat(Math.round(imageData.ratio * 100), "%");
if (!this.tooltipping) {
if (options.transition) {
if (this.fading) {
dispatchEvent(tooltipBox, EVENT_TRANSITION_END);
}
addClass(tooltipBox, CLASS_SHOW);
addClass(tooltipBox, CLASS_FADE);
addClass(tooltipBox, CLASS_TRANSITION); // Force reflow to enable CSS3 transition
// eslint-disable-next-line
tooltipBox.offsetWidth;
addClass(tooltipBox, CLASS_IN);
} else {
addClass(tooltipBox, CLASS_SHOW);
}
} else {
clearTimeout(this.tooltipping);
}
this.tooltipping = setTimeout(function () {
if (options.transition) {
addListener(tooltipBox, EVENT_TRANSITION_END, function () {
removeClass(tooltipBox, CLASS_SHOW);
removeClass(tooltipBox, CLASS_FADE);
removeClass(tooltipBox, CLASS_TRANSITION);
_this7.fading = false;
}, {
once: true
});
removeClass(tooltipBox, CLASS_IN);
_this7.fading = true;
} else {
removeClass(tooltipBox, CLASS_SHOW);
}
_this7.tooltipping = false;
}, 1000);
return this;
},
// Toggle the image size between its natural size and initial size
toggle: function toggle() {
if (this.imageData.ratio === 1) {
this.zoomTo(this.initialImageData.ratio, true);
} else {
this.zoomTo(1, true);
}
return this;
},
// Reset the image to its initial state
reset: function reset() {
if (this.viewed && !this.played) {
this.imageData = assign({}, this.initialImageData);
this.renderImage();
}
return this;
},
// Update viewer when images changed
update: function update() {
var element = this.element,
options = this.options,
isImg = this.isImg; // Destroy viewer if the target image was deleted
if (isImg && !element.parentNode) {
return this.destroy();
}
var images = [];
forEach(isImg ? [element] : element.querySelectorAll('img'), function (image) {
if (options.filter) {
if (options.filter(image)) {
images.push(image);
}
} else {
images.push(image);
}
});
if (!images.length) {
return this;
}
this.images = images;
this.length = images.length;
if (this.ready) {
var indexes = [];
forEach(this.items, function (item, i) {
var img = item.querySelector('img');
var image = images[i];
if (image) {
if (image.src !== img.src) {
indexes.push(i);
}
} else {
indexes.push(i);
}
});
setStyle(this.list, {
width: 'auto'
});
this.initList();
if (this.isShown) {
if (this.length) {
if (this.viewed) {
var index = indexes.indexOf(this.index);
if (index >= 0) {
this.viewed = false;
this.view(Math.max(this.index - (index + 1), 0));
} else {
addClass(this.items[this.index], CLASS_ACTIVE);
}
}
} else {
this.image = null;
this.viewed = false;
this.index = 0;
this.imageData = {};
this.canvas.innerHTML = '';
this.title.innerHTML = '';
}
}
} else {
this.build();
}
return this;
},
// Destroy the viewer
destroy: function destroy() {
var element = this.element,
options = this.options;
if (!element[NAMESPACE]) {
return this;
}
this.destroyed = true;
if (this.ready) {
if (this.played) {
this.stop();
}
if (options.inline) {
if (this.fulled) {
this.exit();
}
this.unbind();
} else if (this.isShown) {
if (this.viewing) {
if (this.imageRendering) {
this.imageRendering.abort();
} else if (this.imageInitializing) {
this.imageInitializing.abort();
}
}
if (this.hiding) {
this.transitioning.abort();
}
this.hidden();
} else if (this.showing) {
this.transitioning.abort();
this.hidden();
}
this.ready = false;
this.viewer.parentNode.removeChild(this.viewer);
} else if (options.inline) {
if (this.delaying) {
this.delaying.abort();
} else if (this.initializing) {
this.initializing.abort();
}
}
if (!options.inline) {
removeListener(element, EVENT_CLICK, this.onStart);
}
element[NAMESPACE] = undefined;
return this;
}
};
var others = {
open: function open() {
var body = this.body;
addClass(body, CLASS_OPEN);
body.style.paddingRight = "".concat(this.scrollbarWidth + (parseFloat(this.initialBodyPaddingRight) || 0), "px");
},
close: function close() {
var body = this.body;
removeClass(body, CLASS_OPEN);
body.style.paddingRight = this.initialBodyPaddingRight;
},
shown: function shown() {
var element = this.element,
options = this.options;
this.fulled = true;
this.isShown = true;
this.render();
this.bind();
this.showing = false;
if (isFunction(options.shown)) {
addListener(element, EVENT_SHOWN, options.shown, {
once: true
});
}
if (dispatchEvent(element, EVENT_SHOWN) === false) {
return;
}
if (this.ready && this.isShown && !this.hiding) {
this.view(this.index);
}
},
hidden: function hidden() {
var element = this.element,
options = this.options;
this.fulled = false;
this.viewed = false;
this.isShown = false;
this.close();
this.unbind();
addClass(this.viewer, CLASS_HIDE);
this.resetList();
this.resetImage();
this.hiding = false;
if (!this.destroyed) {
if (isFunction(options.hidden)) {
addListener(element, EVENT_HIDDEN, options.hidden, {
once: true
});
}
dispatchEvent(element, EVENT_HIDDEN);
}
},
requestFullscreen: function requestFullscreen() {
var document = this.element.ownerDocument;
if (this.fulled && !document.fullscreenElement && !document.mozFullScreenElement && !document.webkitFullscreenElement && !document.msFullscreenElement) {
var documentElement = document.documentElement;
if (documentElement.requestFullscreen) {
documentElement.requestFullscreen();
} else if (documentElement.msRequestFullscreen) {
documentElement.msRequestFullscreen();
} else if (documentElement.mozRequestFullScreen) {
documentElement.mozRequestFullScreen();
} else if (documentElement.webkitRequestFullscreen) {
documentElement.webkitRequestFullscreen(Element.ALLOW_KEYBOARD_INPUT);
}
}
},
exitFullscreen: function exitFullscreen() {
if (this.fulled) {
var document = this.element.ownerDocument;
if (document.exitFullscreen) {
document.exitFullscreen();
} else if (document.msExitFullscreen) {
document.msExitFullscreen();
} else if (document.mozCancelFullScreen) {
document.mozCancelFullScreen();
} else if (document.webkitExitFullscreen) {
document.webkitExitFullscreen();
}
}
},
change: function change(e) {
var options = this.options,
pointers = this.pointers;
var pointer = pointers[Object.keys(pointers)[0]];
var offsetX = pointer.endX - pointer.startX;
var offsetY = pointer.endY - pointer.startY;
switch (this.action) {
// Move the current image
case ACTION_MOVE:
this.move(offsetX, offsetY);
break;
// Zoom the current image
case ACTION_ZOOM:
this.zoom(getMaxZoomRatio(pointers), false, e);
break;
case ACTION_SWITCH:
{
this.action = 'switched';
var absoluteOffsetX = Math.abs(offsetX);
if (absoluteOffsetX > 1 && absoluteOffsetX > Math.abs(offsetY)) {
// Empty `pointers` as `touchend` event will not be fired after swiped in iOS browsers.
this.pointers = {};
if (offsetX > 1) {
this.prev(options.loop);
} else if (offsetX < -1) {
this.next(options.loop);
}
}
break;
}
default:
} // Override
forEach(pointers, function (p) {
p.startX = p.endX;
p.startY = p.endY;
});
},
isSwitchable: function isSwitchable() {
var imageData = this.imageData,
viewerData = this.viewerData;
return this.length > 1 && imageData.left >= 0 && imageData.top >= 0 && imageData.width <= viewerData.width && imageData.height <= viewerData.height;
}
};
var AnotherViewer = WINDOW.Viewer;
var Viewer =
/*#__PURE__*/
function () {
/**
* Create a new Viewer.
* @param {Element} element - The target element for viewing.
* @param {Object} [options={}] - The configuration options.
*/
function Viewer(element) {
var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
_classCallCheck(this, Viewer);
if (!element || element.nodeType !== 1) {
throw new Error('The first argument is required and must be an element.');
}
this.element = element;
this.options = assign({}, DEFAULTS, isPlainObject(options) && options);
this.action = false;
this.fading = false;
this.fulled = false;
this.hiding = false;
this.imageData = {};
this.index = this.options.initialViewIndex;
this.isImg = false;
this.isShown = false;
this.length = 0;
this.played = false;
this.playing = false;
this.pointers = {};
this.ready = false;
this.showing = false;
this.timeout = false;
this.tooltipping = false;
this.viewed = false;
this.viewing = false;
this.wheeling = false;
this.zooming = false;
this.init();
}
_createClass(Viewer, [{
key: "init",
value: function init() {
var _this = this;
var element = this.element,
options = this.options;
if (element[NAMESPACE]) {
return;
}
element[NAMESPACE] = this;
var isImg = element.tagName.toLowerCase() === 'img';
var images = [];
forEach(isImg ? [element] : element.querySelectorAll('img'), function (image) {
if (isFunction(options.filter)) {
if (options.filter.call(_this, image)) {
images.push(image);
}
} else {
images.push(image);
}
});
if (!images.length) {
return;
}
this.isImg = isImg;
this.length = images.length;
this.images = images;
var ownerDocument = element.ownerDocument;
var body = ownerDocument.body || ownerDocument.documentElement;
this.body = body;
this.scrollbarWidth = window.innerWidth - ownerDocument.documentElement.clientWidth;
this.initialBodyPaddingRight = window.getComputedStyle(body).paddingRight; // Override `transition` option if it is not supported
if (isUndefined(document.createElement(NAMESPACE).style.transition)) {
options.transition = false;
}
if (options.inline) {
var count = 0;
var progress = function progress() {
count += 1;
if (count === _this.length) {
var timeout;
_this.initializing = false;
_this.delaying = {
abort: function abort() {
clearTimeout(timeout);
}
}; // build asynchronously to keep `this.viewer` is accessible in `ready` event handler.
timeout = setTimeout(function () {
_this.delaying = false;
_this.build();
}, 0);
}
};
this.initializing = {
abort: function abort() {
forEach(images, function (image) {
if (!image.complete) {
removeListener(image, EVENT_LOAD, progress);
}
});
}
};
forEach(images, function (image) {
if (image.complete) {
progress();
} else {
addListener(image, EVENT_LOAD, progress, {
once: true
});
}
});
} else {
addListener(element, EVENT_CLICK, this.onStart = function (_ref) {
var target = _ref.target;
if (target.tagName.toLowerCase() === 'img' && (!isFunction(options.filter) || options.filter.call(_this, target))) {
_this.view(_this.images.indexOf(target));
}
});
}
}
}, {
key: "build",
value: function build() {
if (this.ready) {
return;
}
var element = this.element,
options = this.options;
var parent = element.parentNode;
var template = document.createElement('div');
template.innerHTML = TEMPLATE;
var viewer = template.querySelector(".".concat(NAMESPACE, "-container"));
var title = viewer.querySelector(".".concat(NAMESPACE, "-title"));
var toolbar = viewer.querySelector(".".concat(NAMESPACE, "-toolbar"));
var navbar = viewer.querySelector(".".concat(NAMESPACE, "-navbar"));
var button = viewer.querySelector(".".concat(NAMESPACE, "-button"));
var canvas = viewer.querySelector(".".concat(NAMESPACE, "-canvas"));
this.parent = parent;
this.viewer = viewer;
this.title = title;
this.toolbar = toolbar;
this.navbar = navbar;
this.button = button;
this.canvas = canvas;
this.footer = viewer.querySelector(".".concat(NAMESPACE, "-footer"));
this.tooltipBox = viewer.querySelector(".".concat(NAMESPACE, "-tooltip"));
this.player = viewer.querySelector(".".concat(NAMESPACE, "-player"));
this.list = viewer.querySelector(".".concat(NAMESPACE, "-list"));
addClass(title, !options.title ? CLASS_HIDE : getResponsiveClass(Array.isArray(options.title) ? options.title[0] : options.title));
addClass(navbar, !options.navbar ? CLASS_HIDE : getResponsiveClass(options.navbar));
toggleClass(button, CLASS_HIDE, !options.button);
if (options.backdrop) {
addClass(viewer, "".concat(NAMESPACE, "-backdrop"));
if (!options.inline && options.backdrop === true) {
setData(canvas, DATA_ACTION, 'hide');
}
}
if (isString(options.className) && options.className) {
// In case there are multiple class names
options.className.split(REGEXP_SPACES).forEach(function (className) {
addClass(viewer, className);
});
}
if (options.toolbar) {
var list = document.createElement('ul');
var custom = isPlainObject(options.toolbar);
var zoomButtons = BUTTONS.slice(0, 3);
var rotateButtons = BUTTONS.slice(7, 9);
var scaleButtons = BUTTONS.slice(9);
if (!custom) {
addClass(toolbar, getResponsiveClass(options.toolbar));
}
forEach(custom ? options.toolbar : BUTTONS, function (value, index) {
var deep = custom && isPlainObject(value);
var name = custom ? hyphenate(index) : value;
var show = deep && !isUndefined(value.show) ? value.show : value;
if (!show || !options.zoomable && zoomButtons.indexOf(name) !== -1 || !options.rotatable && rotateButtons.indexOf(name) !== -1 || !options.scalable && scaleButtons.indexOf(name) !== -1) {
return;
}
var size = deep && !isUndefined(value.size) ? value.size : value;
var click = deep && !isUndefined(value.click) ? value.click : value;
var item = document.createElement('li');
item.setAttribute('role', 'button');
addClass(item, "".concat(NAMESPACE, "-").concat(name));
if (!isFunction(click)) {
setData(item, DATA_ACTION, name);
}
if (isNumber(show)) {
addClass(item, getResponsiveClass(show));
}
if (['small', 'large'].indexOf(size) !== -1) {
addClass(item, "".concat(NAMESPACE, "-").concat(size));
} else if (name === 'play') {
addClass(item, "".concat(NAMESPACE, "-large"));
}
if (isFunction(click)) {
addListener(item, EVENT_CLICK, click);
}
list.appendChild(item);
});
toolbar.appendChild(list);
} else {
addClass(toolbar, CLASS_HIDE);
}
if (!options.rotatable) {
var rotates = toolbar.querySelectorAll('li[class*="rotate"]');
addClass(rotates, CLASS_INVISIBLE);
forEach(rotates, function (rotate) {
toolbar.appendChild(rotate);
});
}
if (options.inline) {
addClass(button, CLASS_FULLSCREEN);
setStyle(viewer, {
zIndex: options.zIndexInline
});
if (window.getComputedStyle(parent).position === 'static') {
setStyle(parent, {
position: 'relative'
});
}
parent.insertBefore(viewer, element.nextSibling);
} else {
addClass(button, CLASS_CLOSE);
addClass(viewer, CLASS_FIXED);
addClass(viewer, CLASS_FADE);
addClass(viewer, CLASS_HIDE);
setStyle(viewer, {
zIndex: options.zIndex
});
var container = options.container;
if (isString(container)) {
container = element.ownerDocument.querySelector(container);
}
if (!container) {
container = this.body;
}
container.appendChild(viewer);
}
if (options.inline) {
this.render();
this.bind();
this.isShown = true;
}
this.ready = true;
if (isFunction(options.ready)) {
addListener(element, EVENT_READY, options.ready, {
once: true
});
}
if (dispatchEvent(element, EVENT_READY) === false) {
this.ready = false;
return;
}
if (this.ready && options.inline) {
this.view(this.index);
}
}
/**
* Get the no conflict viewer class.
* @returns {Viewer} The viewer class.
*/
}], [{
key: "noConflict",
value: function noConflict() {
window.Viewer = AnotherViewer;
return Viewer;
}
/**
* Change the default options.
* @param {Object} options - The new default options.
*/
}, {
key: "setDefaults",
value: function setDefaults(options) {
assign(DEFAULTS, isPlainObject(options) && options);
}
}]);
return Viewer;
}();
assign(Viewer.prototype, render, events, handlers, methods, others);
export default Viewer;
/*!
* Viewer.js v1.3.0
* https://fengyuanchen.github.io/viewerjs
*
* Copyright 2015-present Chen Fengyuan
* Released under the MIT license
*
* Date: 2018-10-25T12:41:54.899Z
*/
(function (global, factory) {
typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :
typeof define === 'function' && define.amd ? define(factory) :
(global.Viewer = factory());
}(this, (function () { 'use strict';
function _typeof(obj) {
if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") {
_typeof = function (obj) {
return typeof obj;
};
} else {
_typeof = function (obj) {
return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj;
};
}
return _typeof(obj);
}
function _classCallCheck(instance, Constructor) {
if (!(instance instanceof Constructor)) {
throw new TypeError("Cannot call a class as a function");
}
}
function _defineProperties(target, props) {
for (var i = 0; i < props.length; i++) {
var descriptor = props[i];
descriptor.enumerable = descriptor.enumerable || false;
descriptor.configurable = true;
if ("value" in descriptor) descriptor.writable = true;
Object.defineProperty(target, descriptor.key, descriptor);
}
}
function _createClass(Constructor, protoProps, staticProps) {
if (protoProps) _defineProperties(Constructor.prototype, protoProps);
if (staticProps) _defineProperties(Constructor, staticProps);
return Constructor;
}
var DEFAULTS = {
/**
* Enable a modal backdrop, specify `static` for a backdrop
* which doesn't close the modal on click.
* @type {boolean}
*/
backdrop: true,
/**
* Show the button on the top-right of the viewer.
* @type {boolean}
*/
button: true,
/**
* Show the navbar.
* @type {boolean | number}
*/
navbar: true,
/**
* Specify the visibility and the content of the title.
* @type {boolean | number | Function | Array}
*/
title: true,
/**
* Show the toolbar.
* @type {boolean | number | Object}
*/
toolbar: true,
/**
* Custom class name(s) to add to the viewer's root element.
* @type {string}
*/
className: '',
/**
* Define where to put the viewer in modal mode.
* @type {string | Element}
*/
container: 'body',
/**
* Filter the images for viewing. Return true if the image is viewable.
* @type {Function}
*/
filter: null,
/**
* Enable to request fullscreen when play.
* @type {boolean}
*/
fullscreen: true,
/**
* Define the initial index of image for viewing.
* @type {number}
*/
initialViewIndex: 0,
/**
* Enable inline mode.
* @type {boolean}
*/
inline: false,
/**
* The amount of time to delay between automatically cycling an image when playing.
* @type {number}
*/
interval: 5000,
/**
* Enable keyboard support.
* @type {boolean}
*/
keyboard: true,
/**
* Indicate if show a loading spinner when load image or not.
* @type {boolean}
*/
loading: true,
/**
* Indicate if enable loop viewing or not.
* @type {boolean}
*/
loop: true,
/**
* Min width of the viewer in inline mode.
* @type {number}
*/
minWidth: 200,
/**
* Min height of the viewer in inline mode.
* @type {number}
*/
minHeight: 100,
/**
* Enable to move the image.
* @type {boolean}
*/
movable: true,
/**
* Enable to zoom the image.
* @type {boolean}
*/
zoomable: true,
/**
* Enable to rotate the image.
* @type {boolean}
*/
rotatable: true,
/**
* Enable to scale the image.
* @type {boolean}
*/
scalable: true,
/**
* Indicate if toggle the image size between its natural size
* and initial size when double click on the image or not.
* @type {boolean}
*/
toggleOnDblclick: true,
/**
* Show the tooltip with image ratio (percentage) when zoom in or zoom out.
* @type {boolean}
*/
tooltip: true,
/**
* Enable CSS3 Transition for some special elements.
* @type {boolean}
*/
transition: true,
/**
* Define the CSS `z-index` value of viewer in modal mode.
* @type {number}
*/
zIndex: 2015,
/**
* Define the CSS `z-index` value of viewer in inline mode.
* @type {number}
*/
zIndexInline: 0,
/**
* Define the ratio when zoom the image by wheeling mouse.
* @type {number}
*/
zoomRatio: 0.1,
/**
* Define the min ratio of the image when zoom out.
* @type {number}
*/
minZoomRatio: 0.01,
/**
* Define the max ratio of the image when zoom in.
* @type {number}
*/
maxZoomRatio: 100,
/**
* Define where to get the original image URL for viewing.
* @type {string | Function}
*/
url: 'src',
/**
* Event shortcuts.
* @type {Function}
*/
ready: null,
show: null,
shown: null,
hide: null,
hidden: null,
view: null,
viewed: null,
zoom: null,
zoomed: null
};
var TEMPLATE = '<div class="viewer-container" touch-action="none">' + '<div class="viewer-canvas"></div>' + '<div class="viewer-footer">' + '<div class="viewer-title"></div>' + '<div class="viewer-toolbar"></div>' + '<div class="viewer-navbar">' + '<ul class="viewer-list"></ul>' + '</div>' + '</div>' + '<div class="viewer-tooltip"></div>' + '<div role="button" class="viewer-button" data-viewer-action="mix"></div>' + '<div class="viewer-player"></div>' + '</div>';
var IN_BROWSER = typeof window !== 'undefined';
var WINDOW = IN_BROWSER ? window : {};
var NAMESPACE = 'viewer'; // Actions
var ACTION_MOVE = 'move';
var ACTION_SWITCH = 'switch';
var ACTION_ZOOM = 'zoom'; // Classes
var CLASS_ACTIVE = "".concat(NAMESPACE, "-active");
var CLASS_CLOSE = "".concat(NAMESPACE, "-close");
var CLASS_FADE = "".concat(NAMESPACE, "-fade");
var CLASS_FIXED = "".concat(NAMESPACE, "-fixed");
var CLASS_FULLSCREEN = "".concat(NAMESPACE, "-fullscreen");
var CLASS_FULLSCREEN_EXIT = "".concat(NAMESPACE, "-fullscreen-exit");
var CLASS_HIDE = "".concat(NAMESPACE, "-hide");
var CLASS_HIDE_MD_DOWN = "".concat(NAMESPACE, "-hide-md-down");
var CLASS_HIDE_SM_DOWN = "".concat(NAMESPACE, "-hide-sm-down");
var CLASS_HIDE_XS_DOWN = "".concat(NAMESPACE, "-hide-xs-down");
var CLASS_IN = "".concat(NAMESPACE, "-in");
var CLASS_INVISIBLE = "".concat(NAMESPACE, "-invisible");
var CLASS_LOADING = "".concat(NAMESPACE, "-loading");
var CLASS_MOVE = "".concat(NAMESPACE, "-move");
var CLASS_OPEN = "".concat(NAMESPACE, "-open");
var CLASS_SHOW = "".concat(NAMESPACE, "-show");
var CLASS_TRANSITION = "".concat(NAMESPACE, "-transition"); // Events
var EVENT_CLICK = 'click';
var EVENT_DBLCLICK = 'dblclick';
var EVENT_DRAG_START = 'dragstart';
var EVENT_HIDDEN = 'hidden';
var EVENT_HIDE = 'hide';
var EVENT_KEY_DOWN = 'keydown';
var EVENT_LOAD = 'load';
var EVENT_POINTER_DOWN = WINDOW.PointerEvent ? 'pointerdown' : 'touchstart mousedown';
var EVENT_POINTER_MOVE = WINDOW.PointerEvent ? 'pointermove' : 'touchmove mousemove';
var EVENT_POINTER_UP = WINDOW.PointerEvent ? 'pointerup pointercancel' : 'touchend touchcancel mouseup';
var EVENT_READY = 'ready';
var EVENT_RESIZE = 'resize';
var EVENT_SHOW = 'show';
var EVENT_SHOWN = 'shown';
var EVENT_TRANSITION_END = 'transitionend';
var EVENT_VIEW = 'view';
var EVENT_VIEWED = 'viewed';
var EVENT_WHEEL = 'wheel mousewheel DOMMouseScroll';
var EVENT_ZOOM = 'zoom';
var EVENT_ZOOMED = 'zoomed'; // Data keys
var DATA_ACTION = "".concat(NAMESPACE, "Action");
var BUTTONS = ['zoom-in', 'zoom-out', 'one-to-one', 'reset', 'prev', 'play', 'next', 'rotate-left', 'rotate-right', 'flip-horizontal', 'flip-vertical']; // RegExps
var REGEXP_SPACES = /\s\s*/;
/**
* Check if the given value is a string.
* @param {*} value - The value to check.
* @returns {boolean} Returns `true` if the given value is a string, else `false`.
*/
function isString(value) {
return typeof value === 'string';
}
/**
* Check if the given value is not a number.
*/
var isNaN = Number.isNaN || WINDOW.isNaN;
/**
* Check if the given value is a number.
* @param {*} value - The value to check.
* @returns {boolean} Returns `true` if the given value is a number, else `false`.
*/
function isNumber(value) {
return typeof value === 'number' && !isNaN(value);
}
/**
* Check if the given value is undefined.
* @param {*} value - The value to check.
* @returns {boolean} Returns `true` if the given value is undefined, else `false`.
*/
function isUndefined(value) {
return typeof value === 'undefined';
}
/**
* Check if the given value is an object.
* @param {*} value - The value to check.
* @returns {boolean} Returns `true` if the given value is an object, else `false`.
*/
function isObject(value) {
return _typeof(value) === 'object' && value !== null;
}
var hasOwnProperty = Object.prototype.hasOwnProperty;
/**
* Check if the given value is a plain object.
* @param {*} value - The value to check.
* @returns {boolean} Returns `true` if the given value is a plain object, else `false`.
*/
function isPlainObject(value) {
if (!isObject(value)) {
return false;
}
try {
var _constructor = value.constructor;
var prototype = _constructor.prototype;
return _constructor && prototype && hasOwnProperty.call(prototype, 'isPrototypeOf');
} catch (e) {
return false;
}
}
/**
* Check if the given value is a function.
* @param {*} value - The value to check.
* @returns {boolean} Returns `true` if the given value is a function, else `false`.
*/
function isFunction(value) {
return typeof value === 'function';
}
/**
* Iterate the given data.
* @param {*} data - The data to iterate.
* @param {Function} callback - The process function for each element.
* @returns {*} The original data.
*/
function forEach(data, callback) {
if (data && isFunction(callback)) {
if (Array.isArray(data) || isNumber(data.length)
/* array-like */
) {
var length = data.length;
var i;
for (i = 0; i < length; i += 1) {
if (callback.call(data, data[i], i, data) === false) {
break;
}
}
} else if (isObject(data)) {
Object.keys(data).forEach(function (key) {
callback.call(data, data[key], key, data);
});
}
}
return data;
}
/**
* Extend the given object.
* @param {*} obj - The object to be extended.
* @param {*} args - The rest objects which will be merged to the first object.
* @returns {Object} The extended object.
*/
var assign = Object.assign || function assign(obj) {
for (var _len = arguments.length, args = new Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {
args[_key - 1] = arguments[_key];
}
if (isObject(obj) && args.length > 0) {
args.forEach(function (arg) {
if (isObject(arg)) {
Object.keys(arg).forEach(function (key) {
obj[key] = arg[key];
});
}
});
}
return obj;
};
var REGEXP_SUFFIX = /^(?:width|height|left|top|marginLeft|marginTop)$/;
/**
* Apply styles to the given element.
* @param {Element} element - The target element.
* @param {Object} styles - The styles for applying.
*/
function setStyle(element, styles) {
var style = element.style;
forEach(styles, function (value, property) {
if (REGEXP_SUFFIX.test(property) && isNumber(value)) {
value += 'px';
}
style[property] = value;
});
}
/**
* Check if the given element has a special class.
* @param {Element} element - The element to check.
* @param {string} value - The class to search.
* @returns {boolean} Returns `true` if the special class was found.
*/
function hasClass(element, value) {
return element.classList ? element.classList.contains(value) : element.className.indexOf(value) > -1;
}
/**
* Add classes to the given element.
* @param {Element} element - The target element.
* @param {string} value - The classes to be added.
*/
function addClass(element, value) {
if (!value) {
return;
}
if (isNumber(element.length)) {
forEach(element, function (elem) {
addClass(elem, value);
});
return;
}
if (element.classList) {
element.classList.add(value);
return;
}
var className = element.className.trim();
if (!className) {
element.className = value;
} else if (className.indexOf(value) < 0) {
element.className = "".concat(className, " ").concat(value);
}
}
/**
* Remove classes from the given element.
* @param {Element} element - The target element.
* @param {string} value - The classes to be removed.
*/
function removeClass(element, value) {
if (!value) {
return;
}
if (isNumber(element.length)) {
forEach(element, function (elem) {
removeClass(elem, value);
});
return;
}
if (element.classList) {
element.classList.remove(value);
return;
}
if (element.className.indexOf(value) >= 0) {
element.className = element.className.replace(value, '');
}
}
/**
* Add or remove classes from the given element.
* @param {Element} element - The target element.
* @param {string} value - The classes to be toggled.
* @param {boolean} added - Add only.
*/
function toggleClass(element, value, added) {
if (!value) {
return;
}
if (isNumber(element.length)) {
forEach(element, function (elem) {
toggleClass(elem, value, added);
});
return;
} // IE10-11 doesn't support the second parameter of `classList.toggle`
if (added) {
addClass(element, value);
} else {
removeClass(element, value);
}
}
var REGEXP_HYPHENATE = /([a-z\d])([A-Z])/g;
/**
* Transform the given string from camelCase to kebab-case
* @param {string} value - The value to transform.
* @returns {string} The transformed value.
*/
function hyphenate(value) {
return value.replace(REGEXP_HYPHENATE, '$1-$2').toLowerCase();
}
/**
* Get data from the given element.
* @param {Element} element - The target element.
* @param {string} name - The data key to get.
* @returns {string} The data value.
*/
function getData(element, name) {
if (isObject(element[name])) {
return element[name];
}
if (element.dataset) {
return element.dataset[name];
}
return element.getAttribute("data-".concat(hyphenate(name)));
}
/**
* Set data to the given element.
* @param {Element} element - The target element.
* @param {string} name - The data key to set.
* @param {string} data - The data value.
*/
function setData(element, name, data) {
if (isObject(data)) {
element[name] = data;
} else if (element.dataset) {
element.dataset[name] = data;
} else {
element.setAttribute("data-".concat(hyphenate(name)), data);
}
}
var onceSupported = function () {
var supported = false;
if (IN_BROWSER) {
var once = false;
var listener = function listener() {};
var options = Object.defineProperty({}, 'once', {
get: function get() {
supported = true;
return once;
},
/**
* This setter can fix a `TypeError` in strict mode
* {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Errors/Getter_only}
* @param {boolean} value - The value to set
*/
set: function set(value) {
once = value;
}
});
WINDOW.addEventListener('test', listener, options);
WINDOW.removeEventListener('test', listener, options);
}
return supported;
}();
/**
* Remove event listener from the target element.
* @param {Element} element - The event target.
* @param {string} type - The event type(s).
* @param {Function} listener - The event listener.
* @param {Object} options - The event options.
*/
function removeListener(element, type, listener) {
var options = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : {};
var handler = listener;
type.trim().split(REGEXP_SPACES).forEach(function (event) {
if (!onceSupported) {
var listeners = element.listeners;
if (listeners && listeners[event] && listeners[event][listener]) {
handler = listeners[event][listener];
delete listeners[event][listener];
if (Object.keys(listeners[event]).length === 0) {
delete listeners[event];
}
if (Object.keys(listeners).length === 0) {
delete element.listeners;
}
}
}
element.removeEventListener(event, handler, options);
});
}
/**
* Add event listener to the target element.
* @param {Element} element - The event target.
* @param {string} type - The event type(s).
* @param {Function} listener - The event listener.
* @param {Object} options - The event options.
*/
function addListener(element, type, listener) {
var options = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : {};
var _handler = listener;
type.trim().split(REGEXP_SPACES).forEach(function (event) {
if (options.once && !onceSupported) {
var _element$listeners = element.listeners,
listeners = _element$listeners === void 0 ? {} : _element$listeners;
_handler = function handler() {
delete listeners[event][listener];
element.removeEventListener(event, _handler, options);
for (var _len2 = arguments.length, args = new Array(_len2), _key2 = 0; _key2 < _len2; _key2++) {
args[_key2] = arguments[_key2];
}
listener.apply(element, args);
};
if (!listeners[event]) {
listeners[event] = {};
}
if (listeners[event][listener]) {
element.removeEventListener(event, listeners[event][listener], options);
}
listeners[event][listener] = _handler;
element.listeners = listeners;
}
element.addEventListener(event, _handler, options);
});
}
/**
* Dispatch event on the target element.
* @param {Element} element - The event target.
* @param {string} type - The event type(s).
* @param {Object} data - The additional event data.
* @returns {boolean} Indicate if the event is default prevented or not.
*/
function dispatchEvent(element, type, data) {
var event; // Event and CustomEvent on IE9-11 are global objects, not constructors
if (isFunction(Event) && isFunction(CustomEvent)) {
event = new CustomEvent(type, {
detail: data,
bubbles: true,
cancelable: true
});
} else {
event = document.createEvent('CustomEvent');
event.initCustomEvent(type, true, true, data);
}
return element.dispatchEvent(event);
}
/**
* Get the offset base on the document.
* @param {Element} element - The target element.
* @returns {Object} The offset data.
*/
function getOffset(element) {
var box = element.getBoundingClientRect();
return {
left: box.left + (window.pageXOffset - document.documentElement.clientLeft),
top: box.top + (window.pageYOffset - document.documentElement.clientTop)
};
}
/**
* Get transforms base on the given object.
* @param {Object} obj - The target object.
* @returns {string} A string contains transform values.
*/
function getTransforms(_ref) {
var rotate = _ref.rotate,
scaleX = _ref.scaleX,
scaleY = _ref.scaleY,
translateX = _ref.translateX,
translateY = _ref.translateY;
var values = [];
if (isNumber(translateX) && translateX !== 0) {
values.push("translateX(".concat(translateX, "px)"));
}
if (isNumber(translateY) && translateY !== 0) {
values.push("translateY(".concat(translateY, "px)"));
} // Rotate should come first before scale to match orientation transform
if (isNumber(rotate) && rotate !== 0) {
values.push("rotate(".concat(rotate, "deg)"));
}
if (isNumber(scaleX) && scaleX !== 1) {
values.push("scaleX(".concat(scaleX, ")"));
}
if (isNumber(scaleY) && scaleY !== 1) {
values.push("scaleY(".concat(scaleY, ")"));
}
var transform = values.length ? values.join(' ') : 'none';
return {
WebkitTransform: transform,
msTransform: transform,
transform: transform
};
}
/**
* Get an image name from an image url.
* @param {string} url - The target url.
* @example
* // picture.jpg
* getImageNameFromURL('http://domain.com/path/to/picture.jpg?size=1280×960')
* @returns {string} A string contains the image name.
*/
function getImageNameFromURL(url) {
return isString(url) ? url.replace(/^.*\//, '').replace(/[?&#].*$/, '') : '';
}
var IS_SAFARI = WINDOW.navigator && /(Macintosh|iPhone|iPod|iPad).*AppleWebKit/i.test(WINDOW.navigator.userAgent);
/**
* Get an image's natural sizes.
* @param {string} image - The target image.
* @param {Function} callback - The callback function.
* @returns {HTMLImageElement} The new image.
*/
function getImageNaturalSizes(image, callback) {
var newImage = document.createElement('img'); // Modern browsers (except Safari)
if (image.naturalWidth && !IS_SAFARI) {
callback(image.naturalWidth, image.naturalHeight);
return newImage;
}
var body = document.body || document.documentElement;
newImage.onload = function () {
callback(newImage.width, newImage.height);
if (!IS_SAFARI) {
body.removeChild(newImage);
}
};
newImage.src = image.src; // iOS Safari will convert the image automatically
// with its orientation once append it into DOM
if (!IS_SAFARI) {
newImage.style.cssText = 'left:0;' + 'max-height:none!important;' + 'max-width:none!important;' + 'min-height:0!important;' + 'min-width:0!important;' + 'opacity:0;' + 'position:absolute;' + 'top:0;' + 'z-index:-1;';
body.appendChild(newImage);
}
return newImage;
}
/**
* Get the related class name of a responsive type number.
* @param {string} type - The responsive type.
* @returns {string} The related class name.
*/
function getResponsiveClass(type) {
switch (type) {
case 2:
return CLASS_HIDE_XS_DOWN;
case 3:
return CLASS_HIDE_SM_DOWN;
case 4:
return CLASS_HIDE_MD_DOWN;
default:
return '';
}
}
/**
* Get the max ratio of a group of pointers.
* @param {string} pointers - The target pointers.
* @returns {number} The result ratio.
*/
function getMaxZoomRatio(pointers) {
var pointers2 = assign({}, pointers);
var ratios = [];
forEach(pointers, function (pointer, pointerId) {
delete pointers2[pointerId];
forEach(pointers2, function (pointer2) {
var x1 = Math.abs(pointer.startX - pointer2.startX);
var y1 = Math.abs(pointer.startY - pointer2.startY);
var x2 = Math.abs(pointer.endX - pointer2.endX);
var y2 = Math.abs(pointer.endY - pointer2.endY);
var z1 = Math.sqrt(x1 * x1 + y1 * y1);
var z2 = Math.sqrt(x2 * x2 + y2 * y2);
var ratio = (z2 - z1) / z1;
ratios.push(ratio);
});
});
ratios.sort(function (a, b) {
return Math.abs(a) < Math.abs(b);
});
return ratios[0];
}
/**
* Get a pointer from an event object.
* @param {Object} event - The target event object.
* @param {boolean} endOnly - Indicates if only returns the end point coordinate or not.
* @returns {Object} The result pointer contains start and/or end point coordinates.
*/
function getPointer(_ref2, endOnly) {
var pageX = _ref2.pageX,
pageY = _ref2.pageY;
var end = {
endX: pageX,
endY: pageY
};
return endOnly ? end : assign({
startX: pageX,
startY: pageY
}, end);
}
/**
* Get the center point coordinate of a group of pointers.
* @param {Object} pointers - The target pointers.
* @returns {Object} The center point coordinate.
*/
function getPointersCenter(pointers) {
var pageX = 0;
var pageY = 0;
var count = 0;
forEach(pointers, function (_ref3) {
var startX = _ref3.startX,
startY = _ref3.startY;
pageX += startX;
pageY += startY;
count += 1;
});
pageX /= count;
pageY /= count;
return {
pageX: pageX,
pageY: pageY
};
}
var render = {
render: function render() {
this.initContainer();
this.initViewer();
this.initList();
this.renderViewer();
},
initContainer: function initContainer() {
this.containerData = {
width: window.innerWidth,
height: window.innerHeight
};
},
initViewer: function initViewer() {
var options = this.options,
parent = this.parent;
var viewerData;
if (options.inline) {
viewerData = {
width: Math.max(parent.offsetWidth, options.minWidth),
height: Math.max(parent.offsetHeight, options.minHeight)
};
this.parentData = viewerData;
}
if (this.fulled || !viewerData) {
viewerData = this.containerData;
}
this.viewerData = assign({}, viewerData);
},
renderViewer: function renderViewer() {
if (this.options.inline && !this.fulled) {
setStyle(this.viewer, this.viewerData);
}
},
initList: function initList() {
var _this = this;
var element = this.element,
options = this.options,
list = this.list;
var items = [];
forEach(this.images, function (image, i) {
var src = image.src;
var alt = image.alt || getImageNameFromURL(src);
var url = options.url;
if (isString(url)) {
url = image.getAttribute(url);
} else if (isFunction(url)) {
url = url.call(_this, image);
}
if (src || url) {
items.push('<li>' + '<img' + " src=\"".concat(src || url, "\"") + ' role="button"' + ' data-viewer-action="view"' + " data-index=\"".concat(i, "\"") + " data-original-url=\"".concat(url || src, "\"") + " alt=\"".concat(alt, "\"") + '>' + '</li>');
}
});
list.innerHTML = items.join('');
this.items = list.getElementsByTagName('li');
forEach(this.items, function (item) {
var image = item.firstElementChild;
setData(image, 'filled', true);
if (options.loading) {
addClass(item, CLASS_LOADING);
}
addListener(image, EVENT_LOAD, function (event) {
if (options.loading) {
removeClass(item, CLASS_LOADING);
}
_this.loadImage(event);
}, {
once: true
});
});
if (options.transition) {
addListener(element, EVENT_VIEWED, function () {
addClass(list, CLASS_TRANSITION);
}, {
once: true
});
}
},
renderList: function renderList(index) {
var i = index || this.index;
var width = this.items[i].offsetWidth || 30;
var outerWidth = width + 1; // 1 pixel of `margin-left` width
// Place the active item in the center of the screen
setStyle(this.list, assign({
width: outerWidth * this.length
}, getTransforms({
translateX: (this.viewerData.width - width) / 2 - outerWidth * i
})));
},
resetList: function resetList() {
var list = this.list;
list.innerHTML = '';
removeClass(list, CLASS_TRANSITION);
setStyle(list, getTransforms({
translateX: 0
}));
},
initImage: function initImage(done) {
var _this2 = this;
var options = this.options,
image = this.image,
viewerData = this.viewerData;
var footerHeight = this.footer.offsetHeight;
var viewerWidth = viewerData.width;
var viewerHeight = Math.max(viewerData.height - footerHeight, footerHeight);
var oldImageData = this.imageData || {};
var sizingImage;
this.imageInitializing = {
abort: function abort() {
sizingImage.onload = null;
}
};
sizingImage = getImageNaturalSizes(image, function (naturalWidth, naturalHeight) {
var aspectRatio = naturalWidth / naturalHeight;
var width = viewerWidth;
var height = viewerHeight;
_this2.imageInitializing = false;
if (viewerHeight * aspectRatio > viewerWidth) {
height = viewerWidth / aspectRatio;
} else {
width = viewerHeight * aspectRatio;
}
width = Math.min(width * 0.9, naturalWidth);
height = Math.min(height * 0.9, naturalHeight);
var imageData = {
naturalWidth: naturalWidth,
naturalHeight: naturalHeight,
aspectRatio: aspectRatio,
ratio: width / naturalWidth,
width: width,
height: height,
left: (viewerWidth - width) / 2,
top: (viewerHeight - height) / 2
};
var initialImageData = assign({}, imageData);
if (options.rotatable) {
imageData.rotate = oldImageData.rotate || 0;
initialImageData.rotate = 0;
}
if (options.scalable) {
imageData.scaleX = oldImageData.scaleX || 1;
imageData.scaleY = oldImageData.scaleY || 1;
initialImageData.scaleX = 1;
initialImageData.scaleY = 1;
}
_this2.imageData = imageData;
_this2.initialImageData = initialImageData;
if (done) {
done();
}
});
},
renderImage: function renderImage(done) {
var _this3 = this;
var image = this.image,
imageData = this.imageData;
setStyle(image, assign({
width: imageData.width,
height: imageData.height,
marginLeft: imageData.left,
marginTop: imageData.top
}, getTransforms(imageData)));
if (done) {
if ((this.viewing || this.zooming) && this.options.transition) {
var onTransitionEnd = function onTransitionEnd() {
_this3.imageRendering = false;
done();
};
this.imageRendering = {
abort: function abort() {
removeListener(image, EVENT_TRANSITION_END, onTransitionEnd);
}
};
addListener(image, EVENT_TRANSITION_END, onTransitionEnd, {
once: true
});
} else {
done();
}
}
},
resetImage: function resetImage() {
// this.image only defined after viewed
if (this.viewing || this.viewed) {
var image = this.image;
if (this.viewing) {
this.viewing.abort();
}
image.parentNode.removeChild(image);
this.image = null;
}
}
};
var events = {
bind: function bind() {
var canvas = this.canvas,
element = this.element,
viewer = this.viewer;
addListener(viewer, EVENT_CLICK, this.onClick = this.click.bind(this));
addListener(viewer, EVENT_WHEEL, this.onWheel = this.wheel.bind(this));
addListener(viewer, EVENT_DRAG_START, this.onDragStart = this.dragstart.bind(this));
if (this.options.toggleOnDblclick) {
addListener(canvas, EVENT_DBLCLICK, this.onDblclick = this.dblclick.bind(this));
}
addListener(canvas, EVENT_POINTER_DOWN, this.onPointerDown = this.pointerdown.bind(this));
addListener(element.ownerDocument, EVENT_POINTER_MOVE, this.onPointerMove = this.pointermove.bind(this));
addListener(element.ownerDocument, EVENT_POINTER_UP, this.onPointerUp = this.pointerup.bind(this));
addListener(element.ownerDocument, EVENT_KEY_DOWN, this.onKeyDown = this.keydown.bind(this));
addListener(window, EVENT_RESIZE, this.onResize = this.resize.bind(this));
},
unbind: function unbind() {
var canvas = this.canvas,
element = this.element,
viewer = this.viewer;
removeListener(viewer, EVENT_CLICK, this.onClick);
removeListener(viewer, EVENT_WHEEL, this.onWheel);
removeListener(viewer, EVENT_DRAG_START, this.onDragStart);
if (this.options.toggleOnDblclick) {
removeListener(canvas, EVENT_DBLCLICK, this.onDblclick);
}
removeListener(canvas, EVENT_POINTER_DOWN, this.onPointerDown);
removeListener(element.ownerDocument, EVENT_POINTER_MOVE, this.onPointerMove);
removeListener(element.ownerDocument, EVENT_POINTER_UP, this.onPointerUp);
removeListener(element.ownerDocument, EVENT_KEY_DOWN, this.onKeyDown);
removeListener(window, EVENT_RESIZE, this.onResize);
}
};
var handlers = {
click: function click(_ref) {
var target = _ref.target;
var options = this.options,
imageData = this.imageData;
var action = getData(target, DATA_ACTION);
switch (action) {
case 'mix':
if (this.played) {
this.stop();
} else if (options.inline) {
if (this.fulled) {
this.exit();
} else {
this.full();
}
} else {
this.hide();
}
break;
case 'hide':
this.hide();
break;
case 'view':
this.view(getData(target, 'index'));
break;
case 'zoom-in':
this.zoom(0.1, true);
break;
case 'zoom-out':
this.zoom(-0.1, true);
break;
case 'one-to-one':
this.toggle();
break;
case 'reset':
this.reset();
break;
case 'prev':
this.prev(options.loop);
break;
case 'play':
this.play(options.fullscreen);
break;
case 'next':
this.next(options.loop);
break;
case 'rotate-left':
this.rotate(-90);
break;
case 'rotate-right':
this.rotate(90);
break;
case 'flip-horizontal':
this.scaleX(-imageData.scaleX || -1);
break;
case 'flip-vertical':
this.scaleY(-imageData.scaleY || -1);
break;
default:
if (this.played) {
this.stop();
}
}
},
dblclick: function dblclick(event) {
if (event.target.parentElement === this.canvas) {
this.toggle();
}
},
load: function load() {
var _this = this;
if (this.timeout) {
clearTimeout(this.timeout);
this.timeout = false;
}
var element = this.element,
options = this.options,
image = this.image,
index = this.index,
viewerData = this.viewerData;
removeClass(image, CLASS_INVISIBLE);
if (options.loading) {
removeClass(this.canvas, CLASS_LOADING);
}
image.style.cssText = 'height:0;' + "margin-left:".concat(viewerData.width / 2, "px;") + "margin-top:".concat(viewerData.height / 2, "px;") + 'max-width:none!important;' + 'position:absolute;' + 'width:0;';
this.initImage(function () {
toggleClass(image, CLASS_MOVE, options.movable);
toggleClass(image, CLASS_TRANSITION, options.transition);
_this.renderImage(function () {
_this.viewed = true;
_this.viewing = false;
if (isFunction(options.viewed)) {
addListener(element, EVENT_VIEWED, options.viewed, {
once: true
});
}
dispatchEvent(element, EVENT_VIEWED, {
originalImage: _this.images[index],
index: index,
image: image
});
});
});
},
loadImage: function loadImage(e) {
var image = e.target;
var parent = image.parentNode;
var parentWidth = parent.offsetWidth || 30;
var parentHeight = parent.offsetHeight || 50;
var filled = !!getData(image, 'filled');
getImageNaturalSizes(image, function (naturalWidth, naturalHeight) {
var aspectRatio = naturalWidth / naturalHeight;
var width = parentWidth;
var height = parentHeight;
if (parentHeight * aspectRatio > parentWidth) {
if (filled) {
width = parentHeight * aspectRatio;
} else {
height = parentWidth / aspectRatio;
}
} else if (filled) {
height = parentWidth / aspectRatio;
} else {
width = parentHeight * aspectRatio;
}
setStyle(image, assign({
width: width,
height: height
}, getTransforms({
translateX: (parentWidth - width) / 2,
translateY: (parentHeight - height) / 2
})));
});
},
keydown: function keydown(e) {
var options = this.options;
if (!this.fulled || !options.keyboard) {
return;
}
switch (e.keyCode || e.which || e.charCode) {
// Escape
case 27:
if (this.played) {
this.stop();
} else if (options.inline) {
if (this.fulled) {
this.exit();
}
} else {
this.hide();
}
break;
// Space
case 32:
if (this.played) {
this.stop();
}
break;
// ArrowLeft
case 37:
this.prev(options.loop);
break;
// ArrowUp
case 38:
// Prevent scroll on Firefox
e.preventDefault(); // Zoom in
this.zoom(options.zoomRatio, true);
break;
// ArrowRight
case 39:
this.next(options.loop);
break;
// ArrowDown
case 40:
// Prevent scroll on Firefox
e.preventDefault(); // Zoom out
this.zoom(-options.zoomRatio, true);
break;
// Ctrl + 0
case 48: // Fall through
// Ctrl + 1
// eslint-disable-next-line no-fallthrough
case 49:
if (e.ctrlKey) {
e.preventDefault();
this.toggle();
}
break;
default:
}
},
dragstart: function dragstart(e) {
if (e.target.tagName.toLowerCase() === 'img') {
e.preventDefault();
}
},
pointerdown: function pointerdown(e) {
var options = this.options,
pointers = this.pointers;
if (!this.viewed || this.showing || this.viewing || this.hiding) {
return;
} // This line is required for preventing page zooming in iOS browsers
e.preventDefault();
if (e.changedTouches) {
forEach(e.changedTouches, function (touch) {
pointers[touch.identifier] = getPointer(touch);
});
} else {
pointers[e.pointerId || 0] = getPointer(e);
}
var action = options.movable ? ACTION_MOVE : false;
if (Object.keys(pointers).length > 1) {
action = ACTION_ZOOM;
} else if ((e.pointerType === 'touch' || e.type === 'touchstart') && this.isSwitchable()) {
action = ACTION_SWITCH;
}
if (options.transition && (action === ACTION_MOVE || action === ACTION_ZOOM)) {
removeClass(this.image, CLASS_TRANSITION);
}
this.action = action;
},
pointermove: function pointermove(e) {
var pointers = this.pointers,
action = this.action;
if (!this.viewed || !action) {
return;
}
e.preventDefault();
if (e.changedTouches) {
forEach(e.changedTouches, function (touch) {
// // The first parameter should not be undefined in some browsers
assign(pointers[touch.identifier] || {}, getPointer(touch, true));
});
} else {
assign(pointers[e.pointerId || 0] || {}, getPointer(e, true));
}
this.change(e);
},
pointerup: function pointerup(e) {
var action = this.action,
pointers = this.pointers;
if (e.changedTouches) {
forEach(e.changedTouches, function (touch) {
delete pointers[touch.identifier];
});
} else {
delete pointers[e.pointerId || 0];
}
if (!action) {
return;
}
e.preventDefault();
if (this.options.transition && (action === ACTION_MOVE || action === ACTION_ZOOM)) {
addClass(this.image, CLASS_TRANSITION);
}
this.action = false;
},
resize: function resize() {
var _this2 = this;
if (!this.isShown || this.hiding) {
return;
}
this.initContainer();
this.initViewer();
this.renderViewer();
this.renderList();
if (this.viewed) {
this.initImage(function () {
_this2.renderImage();
});
}
if (this.played) {
if (this.options.fullscreen && this.fulled && !document.fullscreenElement && !document.mozFullScreenElement && !document.webkitFullscreenElement && !document.msFullscreenElement) {
this.stop();
return;
}
forEach(this.player.getElementsByTagName('img'), function (image) {
addListener(image, EVENT_LOAD, _this2.loadImage.bind(_this2), {
once: true
});
dispatchEvent(image, EVENT_LOAD);
});
}
},
wheel: function wheel(e) {
var _this3 = this;
if (!this.viewed) {
return;
}
e.preventDefault(); // Limit wheel speed to prevent zoom too fast
if (this.wheeling) {
return;
}
this.wheeling = true;
setTimeout(function () {
_this3.wheeling = false;
}, 50);
var ratio = Number(this.options.zoomRatio) || 0.1;
var delta = 1;
if (e.deltaY) {
delta = e.deltaY > 0 ? 1 : -1;
} else if (e.wheelDelta) {
delta = -e.wheelDelta / 120;
} else if (e.detail) {
delta = e.detail > 0 ? 1 : -1;
}
this.zoom(-delta * ratio, true, e);
}
};
var methods = {
/** Show the viewer (only available in modal mode)
* @param {boolean} [immediate=false] - Indicates if show the viewer immediately or not.
* @returns {Viewer} this
*/
show: function show() {
var immediate = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : false;
var element = this.element,
options = this.options;
if (options.inline || this.showing || this.isShown || this.showing) {
return this;
}
if (!this.ready) {
this.build();
if (this.ready) {
this.show(immediate);
}
return this;
}
if (isFunction(options.show)) {
addListener(element, EVENT_SHOW, options.show, {
once: true
});
}
if (dispatchEvent(element, EVENT_SHOW) === false || !this.ready) {
return this;
}
if (this.hiding) {
this.transitioning.abort();
}
this.showing = true;
this.open();
var viewer = this.viewer;
removeClass(viewer, CLASS_HIDE);
if (options.transition && !immediate) {
var shown = this.shown.bind(this);
this.transitioning = {
abort: function abort() {
removeListener(viewer, EVENT_TRANSITION_END, shown);
removeClass(viewer, CLASS_IN);
}
};
addClass(viewer, CLASS_TRANSITION); // Force reflow to enable CSS3 transition
// eslint-disable-next-line
viewer.offsetWidth;
addListener(viewer, EVENT_TRANSITION_END, shown, {
once: true
});
addClass(viewer, CLASS_IN);
} else {
addClass(viewer, CLASS_IN);
this.shown();
}
return this;
},
/**
* Hide the viewer (only available in modal mode)
* @param {boolean} [immediate=false] - Indicates if hide the viewer immediately or not.
* @returns {Viewer} this
*/
hide: function hide() {
var immediate = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : false;
var element = this.element,
options = this.options;
if (options.inline || this.hiding || !(this.isShown || this.showing)) {
return this;
}
if (isFunction(options.hide)) {
addListener(element, EVENT_HIDE, options.hide, {
once: true
});
}
if (dispatchEvent(element, EVENT_HIDE) === false) {
return this;
}
if (this.showing) {
this.transitioning.abort();
}
this.hiding = true;
if (this.played) {
this.stop();
} else if (this.viewing) {
this.viewing.abort();
}
var viewer = this.viewer;
if (options.transition && !immediate) {
var hidden = this.hidden.bind(this);
var hide = function hide() {
addListener(viewer, EVENT_TRANSITION_END, hidden, {
once: true
});
removeClass(viewer, CLASS_IN);
};
this.transitioning = {
abort: function abort() {
if (this.viewed) {
removeListener(this.image, EVENT_TRANSITION_END, hide);
} else {
removeListener(viewer, EVENT_TRANSITION_END, hidden);
}
}
};
if (this.viewed) {
addListener(this.image, EVENT_TRANSITION_END, hide, {
once: true
});
this.zoomTo(0, false, false, true);
} else {
hide();
}
} else {
removeClass(viewer, CLASS_IN);
this.hidden();
}
return this;
},
/**
* View one of the images with image's index
* @param {number} index - The index of the image to view.
* @returns {Viewer} this
*/
view: function view() {
var _this = this;
var index = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : this.options.initialViewIndex;
index = Number(index) || 0;
if (!this.isShown) {
this.index = index;
return this.show();
}
if (this.hiding || this.played || index < 0 || index >= this.length || this.viewed && index === this.index) {
return this;
}
if (this.viewing) {
this.viewing.abort();
}
var element = this.element,
options = this.options,
title = this.title,
canvas = this.canvas;
var item = this.items[index];
var img = item.querySelector('img');
var url = getData(img, 'originalUrl');
var alt = img.getAttribute('alt');
var image = document.createElement('img');
image.src = url;
image.alt = alt;
if (isFunction(options.view)) {
addListener(element, EVENT_VIEW, options.view, {
once: true
});
}
if (dispatchEvent(element, EVENT_VIEW, {
originalImage: this.images[index],
index: index,
image: image
}) === false || !this.isShown || this.hiding || this.played) {
return this;
}
this.image = image;
removeClass(this.items[this.index], CLASS_ACTIVE);
addClass(item, CLASS_ACTIVE);
this.viewed = false;
this.index = index;
this.imageData = {};
addClass(image, CLASS_INVISIBLE);
if (options.loading) {
addClass(canvas, CLASS_LOADING);
}
canvas.innerHTML = '';
canvas.appendChild(image); // Center current item
this.renderList(); // Clear title
title.innerHTML = ''; // Generate title after viewed
var onViewed = function onViewed() {
var imageData = _this.imageData;
var render = Array.isArray(options.title) ? options.title[1] : options.title;
title.innerHTML = isFunction(render) ? render.call(_this, image, imageData) : "".concat(alt, " (").concat(imageData.naturalWidth, " \xD7 ").concat(imageData.naturalHeight, ")");
};
var onLoad;
addListener(element, EVENT_VIEWED, onViewed, {
once: true
});
this.viewing = {
abort: function abort() {
removeListener(element, EVENT_VIEWED, onViewed);
if (image.complete) {
if (this.imageRendering) {
this.imageRendering.abort();
} else if (this.imageInitializing) {
this.imageInitializing.abort();
}
} else {
removeListener(image, EVENT_LOAD, onLoad);
if (this.timeout) {
clearTimeout(this.timeout);
}
}
}
};
if (image.complete) {
this.load();
} else {
addListener(image, EVENT_LOAD, onLoad = this.load.bind(this), {
once: true
});
if (this.timeout) {
clearTimeout(this.timeout);
} // Make the image visible if it fails to load within 1s
this.timeout = setTimeout(function () {
removeClass(image, CLASS_INVISIBLE);
_this.timeout = false;
}, 1000);
}
return this;
},
/**
* View the previous image
* @param {boolean} [loop=false] - Indicate if view the last one
* when it is the first one at present.
* @returns {Viewer} this
*/
prev: function prev() {
var loop = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : false;
var index = this.index - 1;
if (index < 0) {
index = loop ? this.length - 1 : 0;
}
this.view(index);
return this;
},
/**
* View the next image
* @param {boolean} [loop=false] - Indicate if view the first one
* when it is the last one at present.
* @returns {Viewer} this
*/
next: function next() {
var loop = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : false;
var maxIndex = this.length - 1;
var index = this.index + 1;
if (index > maxIndex) {
index = loop ? 0 : maxIndex;
}
this.view(index);
return this;
},
/**
* Move the image with relative offsets.
* @param {number} offsetX - The relative offset distance on the x-axis.
* @param {number} offsetY - The relative offset distance on the y-axis.
* @returns {Viewer} this
*/
move: function move(offsetX, offsetY) {
var imageData = this.imageData;
this.moveTo(isUndefined(offsetX) ? offsetX : imageData.left + Number(offsetX), isUndefined(offsetY) ? offsetY : imageData.top + Number(offsetY));
return this;
},
/**
* Move the image to an absolute point.
* @param {number} x - The x-axis coordinate.
* @param {number} [y=x] - The y-axis coordinate.
* @returns {Viewer} this
*/
moveTo: function moveTo(x) {
var y = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : x;
var imageData = this.imageData;
x = Number(x);
y = Number(y);
if (this.viewed && !this.played && this.options.movable) {
var changed = false;
if (isNumber(x)) {
imageData.left = x;
changed = true;
}
if (isNumber(y)) {
imageData.top = y;
changed = true;
}
if (changed) {
this.renderImage();
}
}
return this;
},
/**
* Zoom the image with a relative ratio.
* @param {number} ratio - The target ratio.
* @param {boolean} [hasTooltip=false] - Indicates if it has a tooltip or not.
* @param {Event} [_originalEvent=null] - The original event if any.
* @returns {Viewer} this
*/
zoom: function zoom(ratio) {
var hasTooltip = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;
var _originalEvent = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : null;
var imageData = this.imageData;
ratio = Number(ratio);
if (ratio < 0) {
ratio = 1 / (1 - ratio);
} else {
ratio = 1 + ratio;
}
this.zoomTo(imageData.width * ratio / imageData.naturalWidth, hasTooltip, _originalEvent);
return this;
},
/**
* Zoom the image to an absolute ratio.
* @param {number} ratio - The target ratio.
* @param {boolean} [hasTooltip=false] - Indicates if it has a tooltip or not.
* @param {Event} [_originalEvent=null] - The original event if any.
* @param {Event} [_zoomable=false] - Indicates if the current zoom is available or not.
* @returns {Viewer} this
*/
zoomTo: function zoomTo(ratio) {
var _this2 = this;
var hasTooltip = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;
var _originalEvent = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : null;
var _zoomable = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : false;
var element = this.element,
options = this.options,
pointers = this.pointers,
imageData = this.imageData;
ratio = Math.max(0, ratio);
if (isNumber(ratio) && this.viewed && !this.played && (_zoomable || options.zoomable)) {
if (!_zoomable) {
var minZoomRatio = Math.max(0.01, options.minZoomRatio);
var maxZoomRatio = Math.min(100, options.maxZoomRatio);
ratio = Math.min(Math.max(ratio, minZoomRatio), maxZoomRatio);
}
if (_originalEvent && ratio > 0.95 && ratio < 1.05) {
ratio = 1;
}
var newWidth = imageData.naturalWidth * ratio;
var newHeight = imageData.naturalHeight * ratio;
var oldRatio = imageData.width / imageData.naturalWidth;
if (isFunction(options.zoom)) {
addListener(element, EVENT_ZOOM, options.zoom, {
once: true
});
}
if (dispatchEvent(element, EVENT_ZOOM, {
ratio: ratio,
oldRatio: oldRatio,
originalEvent: _originalEvent
}) === false) {
return this;
}
this.zooming = true;
if (_originalEvent) {
var offset = getOffset(this.viewer);
var center = pointers && Object.keys(pointers).length ? getPointersCenter(pointers) : {
pageX: _originalEvent.pageX,
pageY: _originalEvent.pageY
}; // Zoom from the triggering point of the event
imageData.left -= (newWidth - imageData.width) * ((center.pageX - offset.left - imageData.left) / imageData.width);
imageData.top -= (newHeight - imageData.height) * ((center.pageY - offset.top - imageData.top) / imageData.height);
} else {
// Zoom from the center of the image
imageData.left -= (newWidth - imageData.width) / 2;
imageData.top -= (newHeight - imageData.height) / 2;
}
imageData.width = newWidth;
imageData.height = newHeight;
imageData.ratio = ratio;
this.renderImage(function () {
_this2.zooming = false;
if (isFunction(options.zoomed)) {
addListener(element, EVENT_ZOOMED, options.zoomed, {
once: true
});
}
dispatchEvent(element, EVENT_ZOOMED, {
ratio: ratio,
oldRatio: oldRatio,
originalEvent: _originalEvent
});
});
if (hasTooltip) {
this.tooltip();
}
}
return this;
},
/**
* Rotate the image with a relative degree.
* @param {number} degree - The rotate degree.
* @returns {Viewer} this
*/
rotate: function rotate(degree) {
this.rotateTo((this.imageData.rotate || 0) + Number(degree));
return this;
},
/**
* Rotate the image to an absolute degree.
* @param {number} degree - The rotate degree.
* @returns {Viewer} this
*/
rotateTo: function rotateTo(degree) {
var imageData = this.imageData;
degree = Number(degree);
if (isNumber(degree) && this.viewed && !this.played && this.options.rotatable) {
imageData.rotate = degree;
this.renderImage();
}
return this;
},
/**
* Scale the image on the x-axis.
* @param {number} scaleX - The scale ratio on the x-axis.
* @returns {Viewer} this
*/
scaleX: function scaleX(_scaleX) {
this.scale(_scaleX, this.imageData.scaleY);
return this;
},
/**
* Scale the image on the y-axis.
* @param {number} scaleY - The scale ratio on the y-axis.
* @returns {Viewer} this
*/
scaleY: function scaleY(_scaleY) {
this.scale(this.imageData.scaleX, _scaleY);
return this;
},
/**
* Scale the image.
* @param {number} scaleX - The scale ratio on the x-axis.
* @param {number} [scaleY=scaleX] - The scale ratio on the y-axis.
* @returns {Viewer} this
*/
scale: function scale(scaleX) {
var scaleY = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : scaleX;
var imageData = this.imageData;
scaleX = Number(scaleX);
scaleY = Number(scaleY);
if (this.viewed && !this.played && this.options.scalable) {
var changed = false;
if (isNumber(scaleX)) {
imageData.scaleX = scaleX;
changed = true;
}
if (isNumber(scaleY)) {
imageData.scaleY = scaleY;
changed = true;
}
if (changed) {
this.renderImage();
}
}
return this;
},
/**
* Play the images
* @param {boolean} [fullscreen=false] - Indicate if request fullscreen or not.
* @returns {Viewer} this
*/
play: function play() {
var _this3 = this;
debugger;
var fullscreen = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : false;
if (!this.isShown || this.played) {
return this;
}
var options = this.options,
player = this.player;
var onLoad = this.loadImage.bind(this);
var list = [];
var total = 0;
var index = 0;
this.played = true;
this.onLoadWhenPlay = onLoad;
if (fullscreen) {
this.requestFullscreen();
}
addClass(player, CLASS_SHOW);
forEach(this.items, function (item, i) {
var img = item.querySelector('img');
var image = document.createElement('img');
image.src = getData(img, 'originalUrl');
image.alt = img.getAttribute('alt');
total += 1;
addClass(image, CLASS_FADE);
toggleClass(image, CLASS_TRANSITION, options.transition);
if (hasClass(item, CLASS_ACTIVE)) {
addClass(image, CLASS_IN);
index = i;
}
list.push(image);
addListener(image, EVENT_LOAD, onLoad, {
once: true
});
player.appendChild(image);
});
if (isNumber(options.interval) && options.interval > 0) {
var play = function play() {
_this3.playing = setTimeout(function () {
removeClass(list[index], CLASS_IN);
index += 1;
index = index < total ? index : 0;
addClass(list[index], CLASS_IN);
play();
}, options.interval);
};
if (total > 1) {
play();
}
}
return this;
},
// Stop play
stop: function stop() {
var _this4 = this;
if (!this.played) {
return this;
}
var player = this.player;
this.played = false;
clearTimeout(this.playing);
forEach(player.getElementsByTagName('img'), function (image) {
removeListener(image, EVENT_LOAD, _this4.onLoadWhenPlay);
});
removeClass(player, CLASS_SHOW);
player.innerHTML = '';
this.exitFullscreen();
return this;
},
// Enter modal mode (only available in inline mode)
full: function full() {
var _this5 = this;
var options = this.options,
viewer = this.viewer,
image = this.image,
list = this.list;
if (!this.isShown || this.played || this.fulled || !options.inline) {
return this;
}
this.fulled = true;
this.open();
addClass(this.button, CLASS_FULLSCREEN_EXIT);
if (options.transition) {
removeClass(list, CLASS_TRANSITION);
if (this.viewed) {
removeClass(image, CLASS_TRANSITION);
}
}
addClass(viewer, CLASS_FIXED);
viewer.setAttribute('style', '');
setStyle(viewer, {
zIndex: options.zIndex
});
this.initContainer();
this.viewerData = assign({}, this.containerData);
this.renderList();
if (this.viewed) {
this.initImage(function () {
_this5.renderImage(function () {
if (options.transition) {
setTimeout(function () {
addClass(image, CLASS_TRANSITION);
addClass(list, CLASS_TRANSITION);
}, 0);
}
});
});
}
return this;
},
// Exit modal mode (only available in inline mode)
exit: function exit() {
var _this6 = this;
var options = this.options,
viewer = this.viewer,
image = this.image,
list = this.list;
if (!this.isShown || this.played || !this.fulled || !options.inline) {
return this;
}
this.fulled = false;
this.close();
removeClass(this.button, CLASS_FULLSCREEN_EXIT);
if (options.transition) {
removeClass(list, CLASS_TRANSITION);
if (this.viewed) {
removeClass(image, CLASS_TRANSITION);
}
}
removeClass(viewer, CLASS_FIXED);
setStyle(viewer, {
zIndex: options.zIndexInline
});
this.viewerData = assign({}, this.parentData);
this.renderViewer();
this.renderList();
if (this.viewed) {
this.initImage(function () {
_this6.renderImage(function () {
if (options.transition) {
setTimeout(function () {
addClass(image, CLASS_TRANSITION);
addClass(list, CLASS_TRANSITION);
}, 0);
}
});
});
}
return this;
},
// Show the current ratio of the image with percentage
tooltip: function tooltip() {
var _this7 = this;
var options = this.options,
tooltipBox = this.tooltipBox,
imageData = this.imageData;
if (!this.viewed || this.played || !options.tooltip) {
return this;
}
tooltipBox.textContent = "".concat(Math.round(imageData.ratio * 100), "%");
if (!this.tooltipping) {
if (options.transition) {
if (this.fading) {
dispatchEvent(tooltipBox, EVENT_TRANSITION_END);
}
addClass(tooltipBox, CLASS_SHOW);
addClass(tooltipBox, CLASS_FADE);
addClass(tooltipBox, CLASS_TRANSITION); // Force reflow to enable CSS3 transition
// eslint-disable-next-line
tooltipBox.offsetWidth;
addClass(tooltipBox, CLASS_IN);
} else {
addClass(tooltipBox, CLASS_SHOW);
}
} else {
clearTimeout(this.tooltipping);
}
this.tooltipping = setTimeout(function () {
if (options.transition) {
addListener(tooltipBox, EVENT_TRANSITION_END, function () {
removeClass(tooltipBox, CLASS_SHOW);
removeClass(tooltipBox, CLASS_FADE);
removeClass(tooltipBox, CLASS_TRANSITION);
_this7.fading = false;
}, {
once: true
});
removeClass(tooltipBox, CLASS_IN);
_this7.fading = true;
} else {
removeClass(tooltipBox, CLASS_SHOW);
}
_this7.tooltipping = false;
}, 1000);
return this;
},
// Toggle the image size between its natural size and initial size
toggle: function toggle() {
if (this.imageData.ratio === 1) {
this.zoomTo(this.initialImageData.ratio, true);
} else {
this.zoomTo(1, true);
}
return this;
},
// Reset the image to its initial state
reset: function reset() {
if (this.viewed && !this.played) {
this.imageData = assign({}, this.initialImageData);
this.renderImage();
}
return this;
},
// Update viewer when images changed
update: function update() {
var element = this.element,
options = this.options,
isImg = this.isImg; // Destroy viewer if the target image was deleted
if (isImg && !element.parentNode) {
return this.destroy();
}
var images = [];
forEach(isImg ? [element] : element.querySelectorAll('img'), function (image) {
if (options.filter) {
if (options.filter(image)) {
images.push(image);
}
} else {
images.push(image);
}
});
if (!images.length) {
return this;
}
this.images = images;
this.length = images.length;
if (this.ready) {
var indexes = [];
forEach(this.items, function (item, i) {
var img = item.querySelector('img');
var image = images[i];
if (image) {
if (image.src !== img.src) {
indexes.push(i);
}
} else {
indexes.push(i);
}
});
setStyle(this.list, {
width: 'auto'
});
this.initList();
if (this.isShown) {
if (this.length) {
if (this.viewed) {
var index = indexes.indexOf(this.index);
if (index >= 0) {
this.viewed = false;
this.view(Math.max(this.index - (index + 1), 0));
} else {
addClass(this.items[this.index], CLASS_ACTIVE);
}
}
} else {
this.image = null;
this.viewed = false;
this.index = 0;
this.imageData = {};
this.canvas.innerHTML = '';
this.title.innerHTML = '';
}
}
} else {
this.build();
}
return this;
},
// Destroy the viewer
destroy: function destroy() {
var element = this.element,
options = this.options;
if (!element[NAMESPACE]) {
return this;
}
this.destroyed = true;
if (this.ready) {
if (this.played) {
this.stop();
}
if (options.inline) {
if (this.fulled) {
this.exit();
}
this.unbind();
} else if (this.isShown) {
if (this.viewing) {
if (this.imageRendering) {
this.imageRendering.abort();
} else if (this.imageInitializing) {
this.imageInitializing.abort();
}
}
if (this.hiding) {
this.transitioning.abort();
}
this.hidden();
} else if (this.showing) {
this.transitioning.abort();
this.hidden();
}
this.ready = false;
this.viewer.parentNode.removeChild(this.viewer);
} else if (options.inline) {
if (this.delaying) {
this.delaying.abort();
} else if (this.initializing) {
this.initializing.abort();
}
}
if (!options.inline) {
removeListener(element, EVENT_CLICK, this.onStart);
}
element[NAMESPACE] = undefined;
return this;
}
};
var others = {
open: function open() {
var body = this.body;
addClass(body, CLASS_OPEN);
body.style.paddingRight = "".concat(this.scrollbarWidth + (parseFloat(this.initialBodyPaddingRight) || 0), "px");
},
close: function close() {
var body = this.body;
removeClass(body, CLASS_OPEN);
body.style.paddingRight = this.initialBodyPaddingRight;
},
shown: function shown() {
var element = this.element,
options = this.options;
this.fulled = true;
this.isShown = true;
this.render();
this.bind();
this.showing = false;
if (isFunction(options.shown)) {
addListener(element, EVENT_SHOWN, options.shown, {
once: true
});
}
if (dispatchEvent(element, EVENT_SHOWN) === false) {
return;
}
if (this.ready && this.isShown && !this.hiding) {
this.view(this.index);
}
},
hidden: function hidden() {
var element = this.element,
options = this.options;
this.fulled = false;
this.viewed = false;
this.isShown = false;
this.close();
this.unbind();
addClass(this.viewer, CLASS_HIDE);
this.resetList();
this.resetImage();
this.hiding = false;
if (!this.destroyed) {
if (isFunction(options.hidden)) {
addListener(element, EVENT_HIDDEN, options.hidden, {
once: true
});
}
dispatchEvent(element, EVENT_HIDDEN);
}
},
requestFullscreen: function requestFullscreen() {
var document = this.element.ownerDocument;
if (this.fulled && !document.fullscreenElement && !document.mozFullScreenElement && !document.webkitFullscreenElement && !document.msFullscreenElement) {
var documentElement = document.documentElement;
if (documentElement.requestFullscreen) {
documentElement.requestFullscreen();
} else if (documentElement.msRequestFullscreen) {
documentElement.msRequestFullscreen();
} else if (documentElement.mozRequestFullScreen) {
documentElement.mozRequestFullScreen();
} else if (documentElement.webkitRequestFullscreen) {
documentElement.webkitRequestFullscreen(Element.ALLOW_KEYBOARD_INPUT);
}
}
},
exitFullscreen: function exitFullscreen() {
if (this.fulled) {
var document = this.element.ownerDocument;
if (document.exitFullscreen) {
document.exitFullscreen();
} else if (document.msExitFullscreen) {
document.msExitFullscreen();
} else if (document.mozCancelFullScreen) {
document.mozCancelFullScreen();
} else if (document.webkitExitFullscreen) {
document.webkitExitFullscreen();
}
}
},
change: function change(e) {
var options = this.options,
pointers = this.pointers;
var pointer = pointers[Object.keys(pointers)[0]];
var offsetX = pointer.endX - pointer.startX;
var offsetY = pointer.endY - pointer.startY;
switch (this.action) {
// Move the current image
case ACTION_MOVE:
this.move(offsetX, offsetY);
break;
// Zoom the current image
case ACTION_ZOOM:
this.zoom(getMaxZoomRatio(pointers), false, e);
break;
case ACTION_SWITCH:
{
this.action = 'switched';
var absoluteOffsetX = Math.abs(offsetX);
if (absoluteOffsetX > 1 && absoluteOffsetX > Math.abs(offsetY)) {
// Empty `pointers` as `touchend` event will not be fired after swiped in iOS browsers.
this.pointers = {};
if (offsetX > 1) {
this.prev(options.loop);
} else if (offsetX < -1) {
this.next(options.loop);
}
}
break;
}
default:
} // Override
forEach(pointers, function (p) {
p.startX = p.endX;
p.startY = p.endY;
});
},
isSwitchable: function isSwitchable() {
var imageData = this.imageData,
viewerData = this.viewerData;
return this.length > 1 && imageData.left >= 0 && imageData.top >= 0 && imageData.width <= viewerData.width && imageData.height <= viewerData.height;
}
};
var AnotherViewer = WINDOW.Viewer;
var Viewer =
/*#__PURE__*/
function () {
/**
* Create a new Viewer.
* @param {Element} element - The target element for viewing.
* @param {Object} [options={}] - The configuration options.
*/
function Viewer(element) {
var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
_classCallCheck(this, Viewer);
if (!element || element.nodeType !== 1) {
throw new Error('The first argument is required and must be an element.');
}
this.element = element;
this.options = assign({}, DEFAULTS, isPlainObject(options) && options);
this.action = false;
this.fading = false;
this.fulled = false;
this.hiding = false;
this.imageData = {};
this.index = this.options.initialViewIndex;
this.isImg = false;
this.isShown = false;
this.length = 0;
this.played = false;
this.playing = false;
this.pointers = {};
this.ready = false;
this.showing = false;
this.timeout = false;
this.tooltipping = false;
this.viewed = false;
this.viewing = false;
this.wheeling = false;
this.zooming = false;
this.init();
}
_createClass(Viewer, [{
key: "init",
value: function init() {
var _this = this;
var element = this.element,
options = this.options;
if (element[NAMESPACE]) {
return;
}
element[NAMESPACE] = this;
var isImg = element.tagName.toLowerCase() === 'img';
var images = [];
forEach(isImg ? [element] : element.querySelectorAll('img'), function (image) {
if (isFunction(options.filter)) {
if (options.filter.call(_this, image)) {
images.push(image);
}
} else {
images.push(image);
}
});
if (!images.length) {
return;
}
this.isImg = isImg;
this.length = images.length;
this.images = images;
var ownerDocument = element.ownerDocument;
var body = ownerDocument.body || ownerDocument.documentElement;
this.body = body;
this.scrollbarWidth = window.innerWidth - ownerDocument.documentElement.clientWidth;
this.initialBodyPaddingRight = window.getComputedStyle(body).paddingRight; // Override `transition` option if it is not supported
if (isUndefined(document.createElement(NAMESPACE).style.transition)) {
options.transition = false;
}
if (options.inline) {
var count = 0;
var progress = function progress() {
count += 1;
if (count === _this.length) {
var timeout;
_this.initializing = false;
_this.delaying = {
abort: function abort() {
clearTimeout(timeout);
}
}; // build asynchronously to keep `this.viewer` is accessible in `ready` event handler.
timeout = setTimeout(function () {
_this.delaying = false;
_this.build();
}, 0);
}
};
this.initializing = {
abort: function abort() {
forEach(images, function (image) {
if (!image.complete) {
removeListener(image, EVENT_LOAD, progress);
}
});
}
};
forEach(images, function (image) {
if (image.complete) {
progress();
} else {
addListener(image, EVENT_LOAD, progress, {
once: true
});
}
});
} else {
addListener(element, EVENT_CLICK, this.onStart = function (_ref) {
var target = _ref.target;
if (target.tagName.toLowerCase() === 'img' && (!isFunction(options.filter) || options.filter.call(_this, target))) {
_this.view(_this.images.indexOf(target));
}
});
}
}
}, {
key: "build",
value: function build() {
if (this.ready) {
return;
}
var element = this.element,
options = this.options;
var parent = element.parentNode;
var template = document.createElement('div');
template.innerHTML = TEMPLATE;
var viewer = template.querySelector(".".concat(NAMESPACE, "-container"));
var title = viewer.querySelector(".".concat(NAMESPACE, "-title"));
var toolbar = viewer.querySelector(".".concat(NAMESPACE, "-toolbar"));
var navbar = viewer.querySelector(".".concat(NAMESPACE, "-navbar"));
var button = viewer.querySelector(".".concat(NAMESPACE, "-button"));
var canvas = viewer.querySelector(".".concat(NAMESPACE, "-canvas"));
this.parent = parent;
this.viewer = viewer;
this.title = title;
this.toolbar = toolbar;
this.navbar = navbar;
this.button = button;
this.canvas = canvas;
this.footer = viewer.querySelector(".".concat(NAMESPACE, "-footer"));
this.tooltipBox = viewer.querySelector(".".concat(NAMESPACE, "-tooltip"));
this.player = viewer.querySelector(".".concat(NAMESPACE, "-player"));
this.list = viewer.querySelector(".".concat(NAMESPACE, "-list"));
addClass(title, !options.title ? CLASS_HIDE : getResponsiveClass(Array.isArray(options.title) ? options.title[0] : options.title));
addClass(navbar, !options.navbar ? CLASS_HIDE : getResponsiveClass(options.navbar));
toggleClass(button, CLASS_HIDE, !options.button);
if (options.backdrop) {
addClass(viewer, "".concat(NAMESPACE, "-backdrop"));
if (!options.inline && options.backdrop === true) {
setData(canvas, DATA_ACTION, 'hide');
}
}
if (isString(options.className) && options.className) {
// In case there are multiple class names
options.className.split(REGEXP_SPACES).forEach(function (className) {
addClass(viewer, className);
});
}
if (options.toolbar) {
var list = document.createElement('ul');
var custom = isPlainObject(options.toolbar);
var zoomButtons = BUTTONS.slice(0, 3);
var rotateButtons = BUTTONS.slice(7, 9);
var scaleButtons = BUTTONS.slice(9);
if (!custom) {
addClass(toolbar, getResponsiveClass(options.toolbar));
}
forEach(custom ? options.toolbar : BUTTONS, function (value, index) {
var deep = custom && isPlainObject(value);
var name = custom ? hyphenate(index) : value;
var show = deep && !isUndefined(value.show) ? value.show : value;
if (!show || !options.zoomable && zoomButtons.indexOf(name) !== -1 || !options.rotatable && rotateButtons.indexOf(name) !== -1 || !options.scalable && scaleButtons.indexOf(name) !== -1) {
return;
}
var size = deep && !isUndefined(value.size) ? value.size : value;
var click = deep && !isUndefined(value.click) ? value.click : value;
var item = document.createElement('li');
item.setAttribute('role', 'button');
addClass(item, "".concat(NAMESPACE, "-").concat(name));
if (!isFunction(click)) {
setData(item, DATA_ACTION, name);
}
if (isNumber(show)) {
addClass(item, getResponsiveClass(show));
}
if (['small', 'large'].indexOf(size) !== -1) {
addClass(item, "".concat(NAMESPACE, "-").concat(size));
} else if (name === 'play') {
addClass(item, "".concat(NAMESPACE, "-large"));
}
if (isFunction(click)) {
addListener(item, EVENT_CLICK, click);
}
list.appendChild(item);
});
toolbar.appendChild(list);
} else {
addClass(toolbar, CLASS_HIDE);
}
if (!options.rotatable) {
var rotates = toolbar.querySelectorAll('li[class*="rotate"]');
addClass(rotates, CLASS_INVISIBLE);
forEach(rotates, function (rotate) {
toolbar.appendChild(rotate);
});
}
if (options.inline) {
addClass(button, CLASS_FULLSCREEN);
setStyle(viewer, {
zIndex: options.zIndexInline
});
if (window.getComputedStyle(parent).position === 'static') {
setStyle(parent, {
position: 'relative'
});
}
parent.insertBefore(viewer, element.nextSibling);
} else {
addClass(button, CLASS_CLOSE);
addClass(viewer, CLASS_FIXED);
addClass(viewer, CLASS_FADE);
addClass(viewer, CLASS_HIDE);
setStyle(viewer, {
zIndex: options.zIndex
});
var container = options.container;
if (isString(container)) {
container = element.ownerDocument.querySelector(container);
}
if (!container) {
container = this.body;
}
container.appendChild(viewer);
}
if (options.inline) {
this.render();
this.bind();
this.isShown = true;
}
this.ready = true;
if (isFunction(options.ready)) {
addListener(element, EVENT_READY, options.ready, {
once: true
});
}
if (dispatchEvent(element, EVENT_READY) === false) {
this.ready = false;
return;
}
if (this.ready && options.inline) {
this.view(this.index);
}
}
/**
* Get the no conflict viewer class.
* @returns {Viewer} The viewer class.
*/
}], [{
key: "noConflict",
value: function noConflict() {
window.Viewer = AnotherViewer;
return Viewer;
}
/**
* Change the default options.
* @param {Object} options - The new default options.
*/
}, {
key: "setDefaults",
value: function setDefaults(options) {
assign(DEFAULTS, isPlainObject(options) && options);
}
}]);
return Viewer;
}();
assign(Viewer.prototype, render, events, handlers, methods, others);
return Viewer;
})));
/*!
* Viewer.js v1.3.0
* https://fengyuanchen.github.io/viewerjs
*
* Copyright 2015-present Chen Fengyuan
* Released under the MIT license
*
* Date: 2018-10-25T12:41:52.459Z
*/.viewer-close:before,.viewer-flip-horizontal:before,.viewer-flip-vertical:before,.viewer-fullscreen-exit:before,.viewer-fullscreen:before,.viewer-next:before,.viewer-one-to-one:before,.viewer-play:before,.viewer-prev:before,.viewer-reset:before,.viewer-rotate-left:before,.viewer-rotate-right:before,.viewer-zoom-in:before,.viewer-zoom-out:before{background-image:url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAARgAAAAUCAYAAABWOyJDAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAALEgAACxIB0t1+/AAAABx0RVh0U29mdHdhcmUAQWRvYmUgRmlyZXdvcmtzIENTNui8sowAAAQPSURBVHic7Zs/iFxVFMa/0U2UaJGksUgnIVhYxVhpjDbZCBmLdAYECxsRFBTUamcXUiSNncgKQbSxsxH8gzAP3FU2jY0kKKJNiiiIghFlccnP4p3nPCdv3p9778vsLOcHB2bfveeb7955c3jvvNkBIMdxnD64a94GHMfZu3iBcRynN7zAOI7TG15gHCeeNUkr8zaxG2lbYDYsdgMbktBsP03jdQwljSXdtBhLOmtjowC9Mg9L+knSlcD8TNKpSA9lBpK2JF2VdDSR5n5J64m0qli399hNFMUlpshQii5jbXTbHGviB0nLNeNDSd9VO4A2UdB2fp+x0eCnaXxWXGA2X0au/3HgN9P4LFCjIANOJdrLr0zzZ+BEpNYDwKbpnQMeAw4m8HjQtM6Z9qa917zPQwFr3M5KgA6J5rTJCdFZJj9/lyvGhsDvwFNVuV2MhhjrK6b9bFiE+j1r87eBl4HDwCF7/U/k+ofAX5b/EXBv5JoLMuILzf3Ap6Z3EzgdqHMCuF7hcQf4HDgeoHnccncqdK/TvSDWffFXI/exICY/xZyqc6XLWF1UFZna4gJ7q8BsRvgd2/xXpo6P+D9dfT7PpECtA3cnWPM0GXGFZh/wgWltA+cDNC7X+AP4GzjZQe+k5dRxuYPeiuXU7e1qwLpDz7dFjXKRaSwuMLvAlG8zZlG+YmiK1HoFqT7wP2z+4Q45TfEGcMt01xLoNZEBTwRqD4BLpnMLeC1A41UmVxsXgXeBayV/Wx20rpTyrpnWRft7p6O/FdqzGrDukPNtkaMoMo3FBdBSQMOnYBCReyf05s126fU9ytfX98+mY54Kxnp7S9K3kj6U9KYdG0h6UdLbkh7poFXMfUnSOyVvL0h6VtIXHbS6nOP+s/Zm9mvyXW1uuC9ohZ72E9uDmXWLJOB1GxsH+DxPftsB8B6wlGDN02TAkxG6+4D3TWsbeC5CS8CDFce+AW500LhhOW2020TRjK3b21HEmgti9m0RonxbdMZeVzV+/4tF3cBpP7E9mKHNL5q8h5g0eYsCMQz0epq8gQrwMXAgcs0FGXGFRcB9wCemF9PkbYqM/Bas7fxLwNeJPdTdpo4itQti8lPMqTpXuozVRVXPpbHI3KkNTB1NfkL81j2mvhDp91HgV9MKuRIqrykj3WPq4rHyL+axj8/qGPmTqi6F9YDlHOvJU6oYcTsh/TYSzWmTE6JT19CtLTJt32D6CmHe0eQn1O8z5AXgT4sx4Vcu0/EQecMydB8z0hUWkTd2t4CrwNEePqMBcAR4mrBbwyXLPWJa8zrXmmLEhNBmfpkuY2102xxrih+pb+ieAb6vGhuA97UcJ5KR8gZ77K+99xxeYBzH6Q3/Z0fHcXrDC4zjOL3hBcZxnN74F+zlvXFWXF9PAAAAAElFTkSuQmCC");background-repeat:no-repeat;color:rgba(0,0,0,0);display:block;font-size:0;height:20px;line-height:0;width:20px}.viewer-zoom-in:before{background-position:0 0;content:"Zoom In"}.viewer-zoom-out:before{background-position:-20px 0;content:"Zoom Out"}.viewer-one-to-one:before{background-position:-40px 0;content:"One to One"}.viewer-reset:before{background-position:-60px 0;content:"Reset"}.viewer-prev:before{background-position:-80px 0;content:"Previous"}.viewer-play:before{background-position:-100px 0;content:"Play"}.viewer-next:before{background-position:-120px 0;content:"Next"}.viewer-rotate-left:before{background-position:-140px 0;content:"Rotate Left"}.viewer-rotate-right:before{background-position:-160px 0;content:"Rotate Right"}.viewer-flip-horizontal:before{background-position:-180px 0;content:"Flip Horizontal"}.viewer-flip-vertical:before{background-position:-200px 0;content:"Flip Vertical"}.viewer-fullscreen:before{background-position:-220px 0;content:"Enter Full Screen"}.viewer-fullscreen-exit:before{background-position:-240px 0;content:"Exit Full Screen"}.viewer-close:before{background-position:-260px 0;content:"Close"}.viewer-container{bottom:0;direction:ltr;font-size:0;left:0;line-height:0;overflow:hidden;position:absolute;right:0;-webkit-tap-highlight-color:transparent;top:0;-webkit-touch-callout:none;-ms-touch-action:none;touch-action:none;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.viewer-container::-moz-selection,.viewer-container ::-moz-selection{background-color:rgba(0,0,0,0)}.viewer-container::selection,.viewer-container ::selection{background-color:rgba(0,0,0,0)}.viewer-container img{display:block;height:auto;max-height:none!important;max-width:none!important;min-height:0!important;min-width:0!important;width:100%}.viewer-canvas{bottom:0;left:0;overflow:hidden;position:absolute;right:0;top:0}.viewer-canvas>img{height:auto;margin:15px auto;max-width:90%!important;width:auto}.viewer-footer{bottom:0;left:0;overflow:hidden;position:absolute;right:0;text-align:center}.viewer-navbar{background-color:rgba(0,0,0,.5);overflow:hidden}.viewer-list{-webkit-box-sizing:content-box;box-sizing:content-box;height:50px;margin:0;overflow:hidden;padding:1px 0}.viewer-list>li{color:rgba(0,0,0,0);cursor:pointer;float:left;font-size:0;height:50px;line-height:0;opacity:.5;overflow:hidden;-webkit-transition:opacity .15s;transition:opacity .15s;width:30px}.viewer-list>li:hover{opacity:.75}.viewer-list>li+li{margin-left:1px}.viewer-list>.viewer-loading{position:relative}.viewer-list>.viewer-loading:after{border-width:2px;height:20px;margin-left:-10px;margin-top:-10px;width:20px}.viewer-list>.viewer-active,.viewer-list>.viewer-active:hover{opacity:1}.viewer-player{background-color:#000;bottom:0;cursor:none;display:none;right:0}.viewer-player,.viewer-player>img{left:0;position:absolute;top:0}.viewer-toolbar>ul{display:inline-block;margin:0 auto 5px;overflow:hidden;padding:3px 0}.viewer-toolbar>ul>li{background-color:rgba(0,0,0,.5);border-radius:50%;cursor:pointer;float:left;height:24px;overflow:hidden;-webkit-transition:background-color .15s;transition:background-color .15s;width:24px}.viewer-toolbar>ul>li:hover{background-color:rgba(0,0,0,.8)}.viewer-toolbar>ul>li:before{margin:2px}.viewer-toolbar>ul>li+li{margin-left:1px}.viewer-toolbar>ul>.viewer-small{height:18px;margin-bottom:3px;margin-top:3px;width:18px}.viewer-toolbar>ul>.viewer-small:before{margin:-1px}.viewer-toolbar>ul>.viewer-large{height:30px;margin-bottom:-3px;margin-top:-3px;width:30px}.viewer-toolbar>ul>.viewer-large:before{margin:5px}.viewer-tooltip{background-color:rgba(0,0,0,.8);border-radius:10px;color:#fff;display:none;font-size:12px;height:20px;left:50%;line-height:20px;margin-left:-25px;margin-top:-10px;position:absolute;text-align:center;top:50%;width:50px}.viewer-title{color:#ccc;display:inline-block;font-size:12px;line-height:1;margin:0 5% 5px;max-width:90%;opacity:.8;overflow:hidden;text-overflow:ellipsis;-webkit-transition:opacity .15s;transition:opacity .15s;white-space:nowrap}.viewer-title:hover{opacity:1}.viewer-button{background-color:rgba(0,0,0,.5);border-radius:50%;cursor:pointer;height:80px;overflow:hidden;position:absolute;right:-40px;top:-40px;-webkit-transition:background-color .15s;transition:background-color .15s;width:80px}.viewer-button:focus,.viewer-button:hover{background-color:rgba(0,0,0,.8)}.viewer-button:before{bottom:15px;left:15px;position:absolute}.viewer-fixed{position:fixed}.viewer-open{overflow:hidden}.viewer-show{display:block}.viewer-hide{display:none}.viewer-backdrop{background-color:rgba(0,0,0,.5)}.viewer-invisible{visibility:hidden}.viewer-move{cursor:move;cursor:-webkit-grab;cursor:grab}.viewer-fade{opacity:0}.viewer-in{opacity:1}.viewer-transition{-webkit-transition:all .3s;transition:all .3s}@-webkit-keyframes viewer-spinner{0%{-webkit-transform:rotate(0deg);transform:rotate(0deg)}to{-webkit-transform:rotate(1turn);transform:rotate(1turn)}}@keyframes viewer-spinner{0%{-webkit-transform:rotate(0deg);transform:rotate(0deg)}to{-webkit-transform:rotate(1turn);transform:rotate(1turn)}}.viewer-loading:after{-webkit-animation:viewer-spinner 1s linear infinite;animation:viewer-spinner 1s linear infinite;border:4px solid hsla(0,0%,100%,.1);border-left-color:hsla(0,0%,100%,.5);border-radius:50%;content:"";display:inline-block;height:40px;left:50%;margin-left:-20px;margin-top:-20px;position:absolute;top:50%;width:40px;z-index:1}@media (max-width:767px){.viewer-hide-xs-down{display:none}}@media (max-width:991px){.viewer-hide-sm-down{display:none}}@media (max-width:1199px){.viewer-hide-md-down{display:none}}
\ No newline at end of file
/*!
* Viewer.js v1.3.0
* https://fengyuanchen.github.io/viewerjs
*
* Copyright 2015-present Chen Fengyuan
* Released under the MIT license
*
* Date: 2018-10-25T12:41:54.899Z
*/
!function(t,i){"object"==typeof exports&&"undefined"!=typeof module?module.exports=i():"function"==typeof define&&define.amd?define(i):t.Viewer=i()}(this,function(){"use strict";function i(t){return(i="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t})(t)}function s(t,i){for(var e=0;e<i.length;e++){var n=i[e];n.enumerable=n.enumerable||!1,n.configurable=!0,"value"in n&&(n.writable=!0),Object.defineProperty(t,n.key,n)}}var o={backdrop:!0,button:!0,navbar:!0,title:!0,toolbar:!0,className:"",container:"body",filter:null,fullscreen:!0,initialViewIndex:0,inline:!1,interval:5e3,keyboard:!0,loading:!0,loop:!0,minWidth:200,minHeight:100,movable:!0,zoomable:!0,rotatable:!0,scalable:!0,toggleOnDblclick:!0,tooltip:!0,transition:!0,zIndex:2015,zIndexInline:0,zoomRatio:.1,minZoomRatio:.01,maxZoomRatio:100,url:"src",ready:null,show:null,shown:null,hide:null,hidden:null,view:null,viewed:null,zoom:null,zoomed:null},a="undefined"!=typeof window,r=a?window:{},p="viewer",c="move",d="switch",u="zoom",m="".concat(p,"-active"),w="".concat(p,"-close"),b="".concat(p,"-fade"),y="".concat(p,"-fixed"),x="".concat(p,"-fullscreen"),h="".concat(p,"-fullscreen-exit"),z="".concat(p,"-hide"),e="".concat(p,"-hide-md-down"),n="".concat(p,"-hide-sm-down"),l="".concat(p,"-hide-xs-down"),f="".concat(p,"-in"),D="".concat(p,"-invisible"),g="".concat(p,"-loading"),v="".concat(p,"-move"),k="".concat(p,"-open"),E="".concat(p,"-show"),I="".concat(p,"-transition"),S="click",T="dblclick",L="dragstart",N="hidden",M="hide",C="keydown",R="load",Y=r.PointerEvent?"pointerdown":"touchstart mousedown",X=r.PointerEvent?"pointermove":"touchmove mousemove",q=r.PointerEvent?"pointerup pointercancel":"touchend touchcancel mouseup",O="ready",F="resize",W="show",A="shown",P="transitionend",H="view",j="viewed",V="wheel mousewheel DOMMouseScroll",B="zoom",K="zoomed",U="".concat(p,"Action"),Z=["zoom-in","zoom-out","one-to-one","reset","prev","play","next","rotate-left","rotate-right","flip-horizontal","flip-vertical"],$=/\s\s*/;function _(t){return"string"==typeof t}var G=Number.isNaN||r.isNaN;function J(t){return"number"==typeof t&&!G(t)}function Q(t){return void 0===t}function tt(t){return"object"===i(t)&&null!==t}var it=Object.prototype.hasOwnProperty;function et(t){if(!tt(t))return!1;try{var i=t.constructor,e=i.prototype;return i&&e&&it.call(e,"isPrototypeOf")}catch(t){return!1}}function nt(t){return"function"==typeof t}function st(i,e){if(i&&nt(e))if(Array.isArray(i)||J(i.length)){var t,n=i.length;for(t=0;t<n&&!1!==e.call(i,i[t],t,i);t+=1);}else tt(i)&&Object.keys(i).forEach(function(t){e.call(i,i[t],t,i)});return i}var ot=Object.assign||function(e){for(var t=arguments.length,i=new Array(1<t?t-1:0),n=1;n<t;n++)i[n-1]=arguments[n];return tt(e)&&0<i.length&&i.forEach(function(i){tt(i)&&Object.keys(i).forEach(function(t){e[t]=i[t]})}),e},at=/^(?:width|height|left|top|marginLeft|marginTop)$/;function rt(t,i){var e=t.style;st(i,function(t,i){at.test(i)&&J(t)&&(t+="px"),e[i]=t})}function ht(t,i){if(i)if(J(t.length))st(t,function(t){ht(t,i)});else if(t.classList)t.classList.add(i);else{var e=t.className.trim();e?e.indexOf(i)<0&&(t.className="".concat(e," ").concat(i)):t.className=i}}function lt(t,i){i&&(J(t.length)?st(t,function(t){lt(t,i)}):t.classList?t.classList.remove(i):0<=t.className.indexOf(i)&&(t.className=t.className.replace(i,"")))}function ct(t,i,e){i&&(J(t.length)?st(t,function(t){ct(t,i,e)}):e?ht(t,i):lt(t,i))}var dt=/([a-z\d])([A-Z])/g;function ut(t){return t.replace(dt,"$1-$2").toLowerCase()}function mt(t,i){return tt(t[i])?t[i]:t.dataset?t.dataset[i]:t.getAttribute("data-".concat(ut(i)))}function ft(t,i,e){tt(e)?t[i]=e:t.dataset?t.dataset[i]=e:t.setAttribute("data-".concat(ut(i)),e)}var gt=function(){var t=!1;if(a){var i=!1,e=function(){},n=Object.defineProperty({},"once",{get:function(){return t=!0,i},set:function(t){i=t}});r.addEventListener("test",e,n),r.removeEventListener("test",e,n)}return t}();function vt(e,t,n){var s=3<arguments.length&&void 0!==arguments[3]?arguments[3]:{},o=n;t.trim().split($).forEach(function(t){if(!gt){var i=e.listeners;i&&i[t]&&i[t][n]&&(o=i[t][n],delete i[t][n],0===Object.keys(i[t]).length&&delete i[t],0===Object.keys(i).length&&delete e.listeners)}e.removeEventListener(t,o,s)})}function pt(o,t,a){var r=3<arguments.length&&void 0!==arguments[3]?arguments[3]:{},h=a;t.trim().split($).forEach(function(n){if(r.once&&!gt){var t=o.listeners,s=void 0===t?{}:t;h=function(){delete s[n][a],o.removeEventListener(n,h,r);for(var t=arguments.length,i=new Array(t),e=0;e<t;e++)i[e]=arguments[e];a.apply(o,i)},s[n]||(s[n]={}),s[n][a]&&o.removeEventListener(n,s[n][a],r),s[n][a]=h,o.listeners=s}o.addEventListener(n,h,r)})}function wt(t,i,e){var n;return nt(Event)&&nt(CustomEvent)?n=new CustomEvent(i,{detail:e,bubbles:!0,cancelable:!0}):(n=document.createEvent("CustomEvent")).initCustomEvent(i,!0,!0,e),t.dispatchEvent(n)}function bt(t){var i=t.rotate,e=t.scaleX,n=t.scaleY,s=t.translateX,o=t.translateY,a=[];J(s)&&0!==s&&a.push("translateX(".concat(s,"px)")),J(o)&&0!==o&&a.push("translateY(".concat(o,"px)")),J(i)&&0!==i&&a.push("rotate(".concat(i,"deg)")),J(e)&&1!==e&&a.push("scaleX(".concat(e,")")),J(n)&&1!==n&&a.push("scaleY(".concat(n,")"));var r=a.length?a.join(" "):"none";return{WebkitTransform:r,msTransform:r,transform:r}}var yt=r.navigator&&/(Macintosh|iPhone|iPod|iPad).*AppleWebKit/i.test(r.navigator.userAgent);function xt(t,i){var e=document.createElement("img");if(t.naturalWidth&&!yt)return i(t.naturalWidth,t.naturalHeight),e;var n=document.body||document.documentElement;return e.onload=function(){i(e.width,e.height),yt||n.removeChild(e)},e.src=t.src,yt||(e.style.cssText="left:0;max-height:none!important;max-width:none!important;min-height:0!important;min-width:0!important;opacity:0;position:absolute;top:0;z-index:-1;",n.appendChild(e)),e}function zt(t){switch(t){case 2:return l;case 3:return n;case 4:return e;default:return""}}function Dt(t,i){var e=t.pageX,n=t.pageY,s={endX:e,endY:n};return i?s:ot({startX:e,startY:n},s)}var t={render:function(){this.initContainer(),this.initViewer(),this.initList(),this.renderViewer()},initContainer:function(){this.containerData={width:window.innerWidth,height:window.innerHeight}},initViewer:function(){var t,i=this.options,e=this.parent;i.inline&&(t={width:Math.max(e.offsetWidth,i.minWidth),height:Math.max(e.offsetHeight,i.minHeight)},this.parentData=t),!this.fulled&&t||(t=this.containerData),this.viewerData=ot({},t)},renderViewer:function(){this.options.inline&&!this.fulled&&rt(this.viewer,this.viewerData)},initList:function(){var a=this,t=this.element,r=this.options,i=this.list,h=[];st(this.images,function(t,i){var e,n=t.src,s=t.alt||(_(e=n)?e.replace(/^.*\//,"").replace(/[?&#].*$/,""):""),o=r.url;_(o)?o=t.getAttribute(o):nt(o)&&(o=o.call(a,t)),(n||o)&&h.push("<li><img"+' src="'.concat(n||o,'"')+' role="button" data-viewer-action="view"'+' data-index="'.concat(i,'"')+' data-original-url="'.concat(o||n,'"')+' alt="'.concat(s,'"')+"></li>")}),i.innerHTML=h.join(""),this.items=i.getElementsByTagName("li"),st(this.items,function(i){var t=i.firstElementChild;ft(t,"filled",!0),r.loading&&ht(i,g),pt(t,R,function(t){r.loading&&lt(i,g),a.loadImage(t)},{once:!0})}),r.transition&&pt(t,j,function(){ht(i,I)},{once:!0})},renderList:function(t){var i=t||this.index,e=this.items[i].offsetWidth||30,n=e+1;rt(this.list,ot({width:n*this.length},bt({translateX:(this.viewerData.width-e)/2-n*i})))},resetList:function(){var t=this.list;t.innerHTML="",lt(t,I),rt(t,bt({translateX:0}))},initImage:function(r){var t,h=this,l=this.options,i=this.image,e=this.viewerData,n=this.footer.offsetHeight,c=e.width,d=Math.max(e.height-n,n),u=this.imageData||{};this.imageInitializing={abort:function(){t.onload=null}},t=xt(i,function(t,i){var e=t/i,n=c,s=d;h.imageInitializing=!1,c<d*e?s=c/e:n=d*e;var o={naturalWidth:t,naturalHeight:i,aspectRatio:e,ratio:(n=Math.min(.9*n,t))/t,width:n,height:s=Math.min(.9*s,i),left:(c-n)/2,top:(d-s)/2},a=ot({},o);l.rotatable&&(o.rotate=u.rotate||0,a.rotate=0),l.scalable&&(o.scaleX=u.scaleX||1,o.scaleY=u.scaleY||1,a.scaleX=1,a.scaleY=1),h.imageData=o,h.initialImageData=a,r&&r()})},renderImage:function(t){var i=this,e=this.image,n=this.imageData;if(rt(e,ot({width:n.width,height:n.height,marginLeft:n.left,marginTop:n.top},bt(n))),t)if((this.viewing||this.zooming)&&this.options.transition){var s=function(){i.imageRendering=!1,t()};this.imageRendering={abort:function(){vt(e,P,s)}},pt(e,P,s,{once:!0})}else t()},resetImage:function(){if(this.viewing||this.viewed){var t=this.image;this.viewing&&this.viewing.abort(),t.parentNode.removeChild(t),this.image=null}}},kt={bind:function(){var t=this.canvas,i=this.element,e=this.viewer;pt(e,S,this.onClick=this.click.bind(this)),pt(e,V,this.onWheel=this.wheel.bind(this)),pt(e,L,this.onDragStart=this.dragstart.bind(this)),this.options.toggleOnDblclick&&pt(t,T,this.onDblclick=this.dblclick.bind(this)),pt(t,Y,this.onPointerDown=this.pointerdown.bind(this)),pt(i.ownerDocument,X,this.onPointerMove=this.pointermove.bind(this)),pt(i.ownerDocument,q,this.onPointerUp=this.pointerup.bind(this)),pt(i.ownerDocument,C,this.onKeyDown=this.keydown.bind(this)),pt(window,F,this.onResize=this.resize.bind(this))},unbind:function(){var t=this.canvas,i=this.element,e=this.viewer;vt(e,S,this.onClick),vt(e,V,this.onWheel),vt(e,L,this.onDragStart),this.options.toggleOnDblclick&&vt(t,T,this.onDblclick),vt(t,Y,this.onPointerDown),vt(i.ownerDocument,X,this.onPointerMove),vt(i.ownerDocument,q,this.onPointerUp),vt(i.ownerDocument,C,this.onKeyDown),vt(window,F,this.onResize)}},Et={click:function(t){var i=t.target,e=this.options,n=this.imageData;switch(mt(i,U)){case"mix":this.played?this.stop():e.inline?this.fulled?this.exit():this.full():this.hide();break;case"hide":this.hide();break;case"view":this.view(mt(i,"index"));break;case"zoom-in":this.zoom(.1,!0);break;case"zoom-out":this.zoom(-.1,!0);break;case"one-to-one":this.toggle();break;case"reset":this.reset();break;case"prev":this.prev(e.loop);break;case"play":this.play(e.fullscreen);break;case"next":this.next(e.loop);break;case"rotate-left":this.rotate(-90);break;case"rotate-right":this.rotate(90);break;case"flip-horizontal":this.scaleX(-n.scaleX||-1);break;case"flip-vertical":this.scaleY(-n.scaleY||-1);break;default:this.played&&this.stop()}},dblclick:function(t){t.target.parentElement===this.canvas&&this.toggle()},load:function(){var t=this;this.timeout&&(clearTimeout(this.timeout),this.timeout=!1);var i=this.element,e=this.options,n=this.image,s=this.index,o=this.viewerData;lt(n,D),e.loading&&lt(this.canvas,g),n.style.cssText="height:0;"+"margin-left:".concat(o.width/2,"px;")+"margin-top:".concat(o.height/2,"px;")+"max-width:none!important;position:absolute;width:0;",this.initImage(function(){ct(n,v,e.movable),ct(n,I,e.transition),t.renderImage(function(){t.viewed=!0,t.viewing=!1,nt(e.viewed)&&pt(i,j,e.viewed,{once:!0}),wt(i,j,{originalImage:t.images[s],index:s,image:n})})})},loadImage:function(t){var o=t.target,i=o.parentNode,a=i.offsetWidth||30,r=i.offsetHeight||50,h=!!mt(o,"filled");xt(o,function(t,i){var e=t/i,n=a,s=r;a<r*e?h?n=r*e:s=a/e:h?s=a/e:n=r*e,rt(o,ot({width:n,height:s},bt({translateX:(a-n)/2,translateY:(r-s)/2})))})},keydown:function(t){var i=this.options;if(this.fulled&&i.keyboard)switch(t.keyCode||t.which||t.charCode){case 27:this.played?this.stop():i.inline?this.fulled&&this.exit():this.hide();break;case 32:this.played&&this.stop();break;case 37:this.prev(i.loop);break;case 38:t.preventDefault(),this.zoom(i.zoomRatio,!0);break;case 39:this.next(i.loop);break;case 40:t.preventDefault(),this.zoom(-i.zoomRatio,!0);break;case 48:case 49:t.ctrlKey&&(t.preventDefault(),this.toggle())}},dragstart:function(t){"img"===t.target.tagName.toLowerCase()&&t.preventDefault()},pointerdown:function(t){var i=this.options,e=this.pointers;if(this.viewed&&!this.showing&&!this.viewing&&!this.hiding){t.preventDefault(),t.changedTouches?st(t.changedTouches,function(t){e[t.identifier]=Dt(t)}):e[t.pointerId||0]=Dt(t);var n=!!i.movable&&c;1<Object.keys(e).length?n=u:"touch"!==t.pointerType&&"touchstart"!==t.type||!this.isSwitchable()||(n=d),!i.transition||n!==c&&n!==u||lt(this.image,I),this.action=n}},pointermove:function(t){var i=this.pointers,e=this.action;this.viewed&&e&&(t.preventDefault(),t.changedTouches?st(t.changedTouches,function(t){ot(i[t.identifier]||{},Dt(t,!0))}):ot(i[t.pointerId||0]||{},Dt(t,!0)),this.change(t))},pointerup:function(t){var i=this.action,e=this.pointers;t.changedTouches?st(t.changedTouches,function(t){delete e[t.identifier]}):delete e[t.pointerId||0],i&&(t.preventDefault(),!this.options.transition||i!==c&&i!==u||ht(this.image,I),this.action=!1)},resize:function(){var i=this;if(this.isShown&&!this.hiding&&(this.initContainer(),this.initViewer(),this.renderViewer(),this.renderList(),this.viewed&&this.initImage(function(){i.renderImage()}),this.played)){if(this.options.fullscreen&&this.fulled&&!document.fullscreenElement&&!document.mozFullScreenElement&&!document.webkitFullscreenElement&&!document.msFullscreenElement)return void this.stop();st(this.player.getElementsByTagName("img"),function(t){pt(t,R,i.loadImage.bind(i),{once:!0}),wt(t,R)})}},wheel:function(t){var i=this;if(this.viewed&&(t.preventDefault(),!this.wheeling)){this.wheeling=!0,setTimeout(function(){i.wheeling=!1},50);var e=Number(this.options.zoomRatio)||.1,n=1;t.deltaY?n=0<t.deltaY?1:-1:t.wheelDelta?n=-t.wheelDelta/120:t.detail&&(n=0<t.detail?1:-1),this.zoom(-n*e,!0,t)}}},It={show:function(){var t=0<arguments.length&&void 0!==arguments[0]&&arguments[0],i=this.element,e=this.options;if(e.inline||this.showing||this.isShown||this.showing)return this;if(!this.ready)return this.build(),this.ready&&this.show(t),this;if(nt(e.show)&&pt(i,W,e.show,{once:!0}),!1===wt(i,W)||!this.ready)return this;this.hiding&&this.transitioning.abort(),this.showing=!0,this.open();var n=this.viewer;if(lt(n,z),e.transition&&!t){var s=this.shown.bind(this);this.transitioning={abort:function(){vt(n,P,s),lt(n,f)}},ht(n,I),n.offsetWidth,pt(n,P,s,{once:!0}),ht(n,f)}else ht(n,f),this.shown();return this},hide:function(){var t=0<arguments.length&&void 0!==arguments[0]&&arguments[0],i=this.element,e=this.options;if(e.inline||this.hiding||!this.isShown&&!this.showing)return this;if(nt(e.hide)&&pt(i,M,e.hide,{once:!0}),!1===wt(i,M))return this;this.showing&&this.transitioning.abort(),this.hiding=!0,this.played?this.stop():this.viewing&&this.viewing.abort();var n=this.viewer;if(e.transition&&!t){var s=this.hidden.bind(this),o=function(){pt(n,P,s,{once:!0}),lt(n,f)};this.transitioning={abort:function(){this.viewed?vt(this.image,P,o):vt(n,P,s)}},this.viewed?(pt(this.image,P,o,{once:!0}),this.zoomTo(0,!1,!1,!0)):o()}else lt(n,f),this.hidden();return this},view:function(){var e=this,t=0<arguments.length&&void 0!==arguments[0]?arguments[0]:this.options.initialViewIndex;if(t=Number(t)||0,!this.isShown)return this.index=t,this.show();if(this.hiding||this.played||t<0||t>=this.length||this.viewed&&t===this.index)return this;this.viewing&&this.viewing.abort();var i=this.element,n=this.options,s=this.title,o=this.canvas,a=this.items[t],r=a.querySelector("img"),h=mt(r,"originalUrl"),l=r.getAttribute("alt"),c=document.createElement("img");if(c.src=h,c.alt=l,nt(n.view)&&pt(i,H,n.view,{once:!0}),!1===wt(i,H,{originalImage:this.images[t],index:t,image:c})||!this.isShown||this.hiding||this.played)return this;this.image=c,lt(this.items[this.index],m),ht(a,m),this.viewed=!1,this.index=t,this.imageData={},ht(c,D),n.loading&&ht(o,g),o.innerHTML="",o.appendChild(c),this.renderList(),s.innerHTML="";var d,u=function(){var t=e.imageData,i=Array.isArray(n.title)?n.title[1]:n.title;s.innerHTML=nt(i)?i.call(e,c,t):"".concat(l," (").concat(t.naturalWidth," × ").concat(t.naturalHeight,")")};return pt(i,j,u,{once:!0}),this.viewing={abort:function(){vt(i,j,u),c.complete?this.imageRendering?this.imageRendering.abort():this.imageInitializing&&this.imageInitializing.abort():(vt(c,R,d),this.timeout&&clearTimeout(this.timeout))}},c.complete?this.load():(pt(c,R,d=this.load.bind(this),{once:!0}),this.timeout&&clearTimeout(this.timeout),this.timeout=setTimeout(function(){lt(c,D),e.timeout=!1},1e3)),this},prev:function(){var t=0<arguments.length&&void 0!==arguments[0]&&arguments[0],i=this.index-1;return i<0&&(i=t?this.length-1:0),this.view(i),this},next:function(){var t=0<arguments.length&&void 0!==arguments[0]&&arguments[0],i=this.length-1,e=this.index+1;return i<e&&(e=t?0:i),this.view(e),this},move:function(t,i){var e=this.imageData;return this.moveTo(Q(t)?t:e.left+Number(t),Q(i)?i:e.top+Number(i)),this},moveTo:function(t){var i=1<arguments.length&&void 0!==arguments[1]?arguments[1]:t,e=this.imageData;if(t=Number(t),i=Number(i),this.viewed&&!this.played&&this.options.movable){var n=!1;J(t)&&(e.left=t,n=!0),J(i)&&(e.top=i,n=!0),n&&this.renderImage()}return this},zoom:function(t){var i=1<arguments.length&&void 0!==arguments[1]&&arguments[1],e=2<arguments.length&&void 0!==arguments[2]?arguments[2]:null,n=this.imageData;return t=(t=Number(t))<0?1/(1-t):1+t,this.zoomTo(n.width*t/n.naturalWidth,i,e),this},zoomTo:function(t){var n,s,o,i,e,a=this,r=1<arguments.length&&void 0!==arguments[1]&&arguments[1],h=2<arguments.length&&void 0!==arguments[2]?arguments[2]:null,l=3<arguments.length&&void 0!==arguments[3]&&arguments[3],c=this.element,d=this.options,u=this.pointers,m=this.imageData;if(J(t=Math.max(0,t))&&this.viewed&&!this.played&&(l||d.zoomable)){if(!l){var f=Math.max(.01,d.minZoomRatio),g=Math.min(100,d.maxZoomRatio);t=Math.min(Math.max(t,f),g)}h&&.95<t&&t<1.05&&(t=1);var v=m.naturalWidth*t,p=m.naturalHeight*t,w=m.width/m.naturalWidth;if(nt(d.zoom)&&pt(c,B,d.zoom,{once:!0}),!1===wt(c,B,{ratio:t,oldRatio:w,originalEvent:h}))return this;if(this.zooming=!0,h){var b=(i=this.viewer,{left:(e=i.getBoundingClientRect()).left+(window.pageXOffset-document.documentElement.clientLeft),top:e.top+(window.pageYOffset-document.documentElement.clientTop)}),y=u&&Object.keys(u).length?(o=s=n=0,st(u,function(t){var i=t.startX,e=t.startY;n+=i,s+=e,o+=1}),{pageX:n/=o,pageY:s/=o}):{pageX:h.pageX,pageY:h.pageY};m.left-=(v-m.width)*((y.pageX-b.left-m.left)/m.width),m.top-=(p-m.height)*((y.pageY-b.top-m.top)/m.height)}else m.left-=(v-m.width)/2,m.top-=(p-m.height)/2;m.width=v,m.height=p,m.ratio=t,this.renderImage(function(){a.zooming=!1,nt(d.zoomed)&&pt(c,K,d.zoomed,{once:!0}),wt(c,K,{ratio:t,oldRatio:w,originalEvent:h})}),r&&this.tooltip()}return this},rotate:function(t){return this.rotateTo((this.imageData.rotate||0)+Number(t)),this},rotateTo:function(t){var i=this.imageData;return J(t=Number(t))&&this.viewed&&!this.played&&this.options.rotatable&&(i.rotate=t,this.renderImage()),this},scaleX:function(t){return this.scale(t,this.imageData.scaleY),this},scaleY:function(t){return this.scale(this.imageData.scaleX,t),this},scale:function(t){var i=1<arguments.length&&void 0!==arguments[1]?arguments[1]:t,e=this.imageData;if(t=Number(t),i=Number(i),this.viewed&&!this.played&&this.options.scalable){var n=!1;J(t)&&(e.scaleX=t,n=!0),J(i)&&(e.scaleY=i,n=!0),n&&this.renderImage()}return this},play:function(){var i=this,t=0<arguments.length&&void 0!==arguments[0]&&arguments[0];if(!this.isShown||this.played)return this;var a=this.options,r=this.player,h=this.loadImage.bind(this),l=[],c=0,d=0;if(this.played=!0,this.onLoadWhenPlay=h,t&&this.requestFullscreen(),ht(r,E),st(this.items,function(t,i){var e,n,s=t.querySelector("img"),o=document.createElement("img");o.src=mt(s,"originalUrl"),o.alt=s.getAttribute("alt"),c+=1,ht(o,b),ct(o,I,a.transition),n=m,((e=t).classList?e.classList.contains(n):-1<e.className.indexOf(n))&&(ht(o,f),d=i),l.push(o),pt(o,R,h,{once:!0}),r.appendChild(o)}),J(a.interval)&&0<a.interval){var e=function t(){i.playing=setTimeout(function(){lt(l[d],f),ht(l[d=(d+=1)<c?d:0],f),t()},a.interval)};1<c&&e()}return this},stop:function(){var i=this;if(!this.played)return this;var t=this.player;return this.played=!1,clearTimeout(this.playing),st(t.getElementsByTagName("img"),function(t){vt(t,R,i.onLoadWhenPlay)}),lt(t,E),t.innerHTML="",this.exitFullscreen(),this},full:function(){var t=this,i=this.options,e=this.viewer,n=this.image,s=this.list;return!this.isShown||this.played||this.fulled||!i.inline||(this.fulled=!0,this.open(),ht(this.button,h),i.transition&&(lt(s,I),this.viewed&&lt(n,I)),ht(e,y),e.setAttribute("style",""),rt(e,{zIndex:i.zIndex}),this.initContainer(),this.viewerData=ot({},this.containerData),this.renderList(),this.viewed&&this.initImage(function(){t.renderImage(function(){i.transition&&setTimeout(function(){ht(n,I),ht(s,I)},0)})})),this},exit:function(){var t=this,i=this.options,e=this.viewer,n=this.image,s=this.list;return this.isShown&&!this.played&&this.fulled&&i.inline&&(this.fulled=!1,this.close(),lt(this.button,h),i.transition&&(lt(s,I),this.viewed&&lt(n,I)),lt(e,y),rt(e,{zIndex:i.zIndexInline}),this.viewerData=ot({},this.parentData),this.renderViewer(),this.renderList(),this.viewed&&this.initImage(function(){t.renderImage(function(){i.transition&&setTimeout(function(){ht(n,I),ht(s,I)},0)})})),this},tooltip:function(){var t=this,i=this.options,e=this.tooltipBox,n=this.imageData;return this.viewed&&!this.played&&i.tooltip&&(e.textContent="".concat(Math.round(100*n.ratio),"%"),this.tooltipping?clearTimeout(this.tooltipping):i.transition?(this.fading&&wt(e,P),ht(e,E),ht(e,b),ht(e,I),e.offsetWidth,ht(e,f)):ht(e,E),this.tooltipping=setTimeout(function(){i.transition?(pt(e,P,function(){lt(e,E),lt(e,b),lt(e,I),t.fading=!1},{once:!0}),lt(e,f),t.fading=!0):lt(e,E),t.tooltipping=!1},1e3)),this},toggle:function(){return 1===this.imageData.ratio?this.zoomTo(this.initialImageData.ratio,!0):this.zoomTo(1,!0),this},reset:function(){return this.viewed&&!this.played&&(this.imageData=ot({},this.initialImageData),this.renderImage()),this},update:function(){var t=this.element,i=this.options,e=this.isImg;if(e&&!t.parentNode)return this.destroy();var s=[];if(st(e?[t]:t.querySelectorAll("img"),function(t){i.filter?i.filter(t)&&s.push(t):s.push(t)}),!s.length)return this;if(this.images=s,this.length=s.length,this.ready){var o=[];if(st(this.items,function(t,i){var e=t.querySelector("img"),n=s[i];n?n.src!==e.src&&o.push(i):o.push(i)}),rt(this.list,{width:"auto"}),this.initList(),this.isShown)if(this.length){if(this.viewed){var n=o.indexOf(this.index);0<=n?(this.viewed=!1,this.view(Math.max(this.index-(n+1),0))):ht(this.items[this.index],m)}}else this.image=null,this.viewed=!1,this.index=0,this.imageData={},this.canvas.innerHTML="",this.title.innerHTML=""}else this.build();return this},destroy:function(){var t=this.element,i=this.options;return t[p]&&(this.destroyed=!0,this.ready?(this.played&&this.stop(),i.inline?(this.fulled&&this.exit(),this.unbind()):this.isShown?(this.viewing&&(this.imageRendering?this.imageRendering.abort():this.imageInitializing&&this.imageInitializing.abort()),this.hiding&&this.transitioning.abort(),this.hidden()):this.showing&&(this.transitioning.abort(),this.hidden()),this.ready=!1,this.viewer.parentNode.removeChild(this.viewer)):i.inline&&(this.delaying?this.delaying.abort():this.initializing&&this.initializing.abort()),i.inline||vt(t,S,this.onStart),t[p]=void 0),this}},St={open:function(){var t=this.body;ht(t,k),t.style.paddingRight="".concat(this.scrollbarWidth+(parseFloat(this.initialBodyPaddingRight)||0),"px")},close:function(){var t=this.body;lt(t,k),t.style.paddingRight=this.initialBodyPaddingRight},shown:function(){var t=this.element,i=this.options;this.fulled=!0,this.isShown=!0,this.render(),this.bind(),this.showing=!1,nt(i.shown)&&pt(t,A,i.shown,{once:!0}),!1!==wt(t,A)&&this.ready&&this.isShown&&!this.hiding&&this.view(this.index)},hidden:function(){var t=this.element,i=this.options;this.fulled=!1,this.viewed=!1,this.isShown=!1,this.close(),this.unbind(),ht(this.viewer,z),this.resetList(),this.resetImage(),this.hiding=!1,this.destroyed||(nt(i.hidden)&&pt(t,N,i.hidden,{once:!0}),wt(t,N))},requestFullscreen:function(){var t=this.element.ownerDocument;if(this.fulled&&!t.fullscreenElement&&!t.mozFullScreenElement&&!t.webkitFullscreenElement&&!t.msFullscreenElement){var i=t.documentElement;i.requestFullscreen?i.requestFullscreen():i.msRequestFullscreen?i.msRequestFullscreen():i.mozRequestFullScreen?i.mozRequestFullScreen():i.webkitRequestFullscreen&&i.webkitRequestFullscreen(Element.ALLOW_KEYBOARD_INPUT)}},exitFullscreen:function(){if(this.fulled){var t=this.element.ownerDocument;t.exitFullscreen?t.exitFullscreen():t.msExitFullscreen?t.msExitFullscreen():t.mozCancelFullScreen?t.mozCancelFullScreen():t.webkitExitFullscreen&&t.webkitExitFullscreen()}},change:function(t){var i,e,h,n=this.options,s=this.pointers,o=s[Object.keys(s)[0]],a=o.endX-o.startX,r=o.endY-o.startY;switch(this.action){case c:this.move(a,r);break;case u:this.zoom((e=ot({},i=s),h=[],st(i,function(r,t){delete e[t],st(e,function(t){var i=Math.abs(r.startX-t.startX),e=Math.abs(r.startY-t.startY),n=Math.abs(r.endX-t.endX),s=Math.abs(r.endY-t.endY),o=Math.sqrt(i*i+e*e),a=(Math.sqrt(n*n+s*s)-o)/o;h.push(a)})}),h.sort(function(t,i){return Math.abs(t)<Math.abs(i)}),h[0]),!1,t);break;case d:this.action="switched";var l=Math.abs(a);1<l&&l>Math.abs(r)&&(this.pointers={},1<a?this.prev(n.loop):a<-1&&this.next(n.loop))}st(s,function(t){t.startX=t.endX,t.startY=t.endY})},isSwitchable:function(){var t=this.imageData,i=this.viewerData;return 1<this.length&&0<=t.left&&0<=t.top&&t.width<=i.width&&t.height<=i.height}},Tt=r.Viewer,Lt=function(){function e(t){var i=1<arguments.length&&void 0!==arguments[1]?arguments[1]:{};if(function(t,i){if(!(t instanceof i))throw new TypeError("Cannot call a class as a function")}(this,e),!t||1!==t.nodeType)throw new Error("The first argument is required and must be an element.");this.element=t,this.options=ot({},o,et(i)&&i),this.action=!1,this.fading=!1,this.fulled=!1,this.hiding=!1,this.imageData={},this.index=this.options.initialViewIndex,this.isImg=!1,this.isShown=!1,this.length=0,this.played=!1,this.playing=!1,this.pointers={},this.ready=!1,this.showing=!1,this.timeout=!1,this.tooltipping=!1,this.viewed=!1,this.viewing=!1,this.wheeling=!1,this.zooming=!1,this.init()}var t,i,n;return t=e,n=[{key:"noConflict",value:function(){return window.Viewer=Tt,e}},{key:"setDefaults",value:function(t){ot(o,et(t)&&t)}}],(i=[{key:"init",value:function(){var e=this,t=this.element,n=this.options;if(!t[p]){t[p]=this;var i="img"===t.tagName.toLowerCase(),s=[];if(st(i?[t]:t.querySelectorAll("img"),function(t){nt(n.filter)?n.filter.call(e,t)&&s.push(t):s.push(t)}),s.length){this.isImg=i,this.length=s.length,this.images=s;var o=t.ownerDocument,a=o.body||o.documentElement;if(this.body=a,this.scrollbarWidth=window.innerWidth-o.documentElement.clientWidth,this.initialBodyPaddingRight=window.getComputedStyle(a).paddingRight,Q(document.createElement(p).style.transition)&&(n.transition=!1),n.inline){var r=0,h=function(){var t;(r+=1)===e.length&&(e.initializing=!1,e.delaying={abort:function(){clearTimeout(t)}},t=setTimeout(function(){e.delaying=!1,e.build()},0))};this.initializing={abort:function(){st(s,function(t){t.complete||vt(t,R,h)})}},st(s,function(t){t.complete?h():pt(t,R,h,{once:!0})})}else pt(t,S,this.onStart=function(t){var i=t.target;"img"!==i.tagName.toLowerCase()||nt(n.filter)&&!n.filter.call(e,i)||e.view(e.images.indexOf(i))})}}}},{key:"build",value:function(){if(!this.ready){var t=this.element,h=this.options,i=t.parentNode,e=document.createElement("div");e.innerHTML='<div class="viewer-container" touch-action="none"><div class="viewer-canvas"></div><div class="viewer-footer"><div class="viewer-title"></div><div class="viewer-toolbar"></div><div class="viewer-navbar"><ul class="viewer-list"></ul></div></div><div class="viewer-tooltip"></div><div role="button" class="viewer-button" data-viewer-action="mix"></div><div class="viewer-player"></div></div>';var n=e.querySelector(".".concat(p,"-container")),s=n.querySelector(".".concat(p,"-title")),o=n.querySelector(".".concat(p,"-toolbar")),a=n.querySelector(".".concat(p,"-navbar")),r=n.querySelector(".".concat(p,"-button")),l=n.querySelector(".".concat(p,"-canvas"));if(this.parent=i,this.viewer=n,this.title=s,this.toolbar=o,this.navbar=a,this.button=r,this.canvas=l,this.footer=n.querySelector(".".concat(p,"-footer")),this.tooltipBox=n.querySelector(".".concat(p,"-tooltip")),this.player=n.querySelector(".".concat(p,"-player")),this.list=n.querySelector(".".concat(p,"-list")),ht(s,h.title?zt(Array.isArray(h.title)?h.title[0]:h.title):z),ht(a,h.navbar?zt(h.navbar):z),ct(r,z,!h.button),h.backdrop&&(ht(n,"".concat(p,"-backdrop")),h.inline||!0!==h.backdrop||ft(l,U,"hide")),_(h.className)&&h.className&&h.className.split($).forEach(function(t){ht(n,t)}),h.toolbar){var c=document.createElement("ul"),d=et(h.toolbar),u=Z.slice(0,3),m=Z.slice(7,9),f=Z.slice(9);d||ht(o,zt(h.toolbar)),st(d?h.toolbar:Z,function(t,i){var e=d&&et(t),n=d?ut(i):t,s=e&&!Q(t.show)?t.show:t;if(s&&(h.zoomable||-1===u.indexOf(n))&&(h.rotatable||-1===m.indexOf(n))&&(h.scalable||-1===f.indexOf(n))){var o=e&&!Q(t.size)?t.size:t,a=e&&!Q(t.click)?t.click:t,r=document.createElement("li");r.setAttribute("role","button"),ht(r,"".concat(p,"-").concat(n)),nt(a)||ft(r,U,n),J(s)&&ht(r,zt(s)),-1!==["small","large"].indexOf(o)?ht(r,"".concat(p,"-").concat(o)):"play"===n&&ht(r,"".concat(p,"-large")),nt(a)&&pt(r,S,a),c.appendChild(r)}}),o.appendChild(c)}else ht(o,z);if(!h.rotatable){var g=o.querySelectorAll('li[class*="rotate"]');ht(g,D),st(g,function(t){o.appendChild(t)})}if(h.inline)ht(r,x),rt(n,{zIndex:h.zIndexInline}),"static"===window.getComputedStyle(i).position&&rt(i,{position:"relative"}),i.insertBefore(n,t.nextSibling);else{ht(r,w),ht(n,y),ht(n,b),ht(n,z),rt(n,{zIndex:h.zIndex});var v=h.container;_(v)&&(v=t.ownerDocument.querySelector(v)),v||(v=this.body),v.appendChild(n)}h.inline&&(this.render(),this.bind(),this.isShown=!0),this.ready=!0,nt(h.ready)&&pt(t,O,h.ready,{once:!0}),!1!==wt(t,O)?this.ready&&h.inline&&this.view(this.index):this.ready=!1}}}])&&s(t.prototype,i),n&&s(t,n),e}();return ot(Lt.prototype,t,kt,Et,It,St),Lt});
\ No newline at end of file
//viewerjs插件引用
var viewer2;
var index = 0;
var links ='';
var arry =[];
var image = new Image();
var setId //计时器
//获取项目名
var pathName = window.document.location.pathname;
var projectName =pathName.substring(0,pathName.substr(1).indexOf('/')+1);
//点击事件
Ext.fly(document).on('click', function(ev){
//获取点击的a链接
var target = ev.getTarget('a[ref=img]');
if (target) {
target.blur();//去掉a标签焦点
// ev.preventDefault();//取消默认事件
index = 0; //索引置空
indexs(target.href); //获取数组
//预览图片
//this.show_viewer_singer(target.href, target.text);
}
//按钮下一页、上一页
var target_next = ev.getTarget('.viewer-next');
var target_prev = ev.getTarget('.viewer-prev');
if (target_next){
target_next.blur();//去掉a标签焦点
ev.preventDefault();//取消事件的默认动作。
clearTimeout(setId);//清除计时器
next(target_next);
}
if (target_prev){
target_prev.blur();//去掉a标签焦点
ev.preventDefault();//取消事件的默认动作。
clearTimeout(setId);//清除计时器
prev(target_prev);
}
}, this);
//获取数组、索引
function indexs(href,staus){
var setItems;
if (staus == '_more'){
setItems = Ext.query('a');
}else{
setItems = Ext.query('a[ref=img]');
}
arry.length=0;//置空数组
Ext.each(setItems, function(item) {
if(staus == '_more'){
if(item.href && item.href.indexOf('javascript:window[\''+'show_viewer_more'+'\']') != -1) {
var list= item.href.split(',');
var id =list[1].replace("\'","").replace("\'","");
arry.push([ links+ id ,item.text]);
}
}else{
if(item.href){
arry.push([item.href,item.text]);
}
}
});
while (arry[index][0] != href) {
index++;
}
}
//上一页
function prev(target_prev){
viewer2.destroy();//销毁容器,退出预览
var src,alt;
var div = document.getElementById('view-imgs');
if (index == 0 ){
index = arry.length-1 ;
}else{
index = -- index ;
}
for (i = 0 ; i < arry.length; i++){
if (index == i){
src = arry[i][0] ;
alt = arry[i][1];
}
}
show_viewer_singer(src, alt);
}
//下一页
function next(target_next){
viewer2.destroy();//销毁预览容器
var src,alt;
if (index == arry.length-1){
index = 0;
}else{
index = ++ index ;
}
for (i = 0 ; i < arry.length; i++){
if (index == i){
src = arry[i][0] ;
alt = arry[i][1];
}
}
show_viewer_singer(src, alt);
}
// 键盘捕捉事件
document.onkeydown=function(ev){
var e =ev || window.event || arguments.callee.caller.arguments[0];
if (e && viewer2.ready){
var keyCode = ev.keyCode;
if (keyCode == 39 || keyCode == 68){ //D
var target_next =Ext.query('.viewer-next');
if (target_next.length == 1){
next(target_next[0]);
}
}else if (keyCode == 37 || keyCode == 65){//A
var target_prev = Ext.query('.viewer-prev');
if (target_prev.length == 1){
prev(target_prev[0]);
}
}else if( keyCode== 87){//W
ev.preventDefault();
viewer2.zoom(0.1,true);
}else if (keyCode==83){//S
ev.preventDefault();
viewer2.zoom(-0.1,true);
}else if (keyCode == 81){//Q
ev.preventDefault();
viewer2.rotate(-90);
}else if (keyCode == 69){//E
ev.preventDefault();
viewer2.rotate(90);
}
}
}
function show_viewer_more(link , id , name ,value) {
if (document.activeElement.tagName == 'A'){
document.activeElement.blur();//去掉a标签焦点
}
var src = link+id; //点击a连接的图片地址
links = link; //数组中的图片地址
index = 0; //索引置空
indexs(src,'_more'); //生成索引
//预览图片
this.show_viewer_singer(src, name);
}
function show_viewer_singer(src, name) {
image.src = src ;
image.alt = index+1 +'/'+ arry.length;
var viewer = new Viewer(image, {
hidden: function() {
viewer.destroy();
},
toolbar: {
zoomIn: 3,
zoomOut: 3,
oneToOne: 3,
reset: 3,
prev: 3,
play: {
show: 3,
size: 'large',
},
next: 3,
rotateLeft: 3,
rotateRight: 3,
flipHorizontal: 3,
flipVertical: 3,
},
navbar:0,
zoomRatio:0.5,
keyboard :true,
});
viewer.show();
viewer2 = viewer;
/*setId =setTimeout(function(){
if(viewer2.image.width !=0 && viewer2.image.height!=0){
viewer2.image.src=projectName+'/viewerjs/img_error.jpg';
viewer2.image.style.cssText = "height: 208px; margin-left: 461px; margin-top: 150.5px; position: absolute; width: 426px; max-width: none !important; transform: none;"
}
if(image.width !=0 && image.height!=0){
image.src=projectName+'/viewerjs/img_error.jpg';
}
},15000);*/
}
\ No newline at end of file
//viewerjs插件引用
function show_viewer_more(link , id , name ,value) {
debugger;
var img ='';
var str = value.split(';;');
var div = document.createElement("div");
var initialViewIndex ='';
for (var i = 0;i < str.length;i++) {
var temp = str[i].split('--');
if (!Aurora.isEmpty(temp[0])) {
var file_name = temp[0].toUpperCase();
var file_suffix = temp[0].substr(temp[0].lastIndexOf('.') + 1).toUpperCase();
if (file_suffix == 'BMP' || file_suffix == 'JPG' || file_suffix == 'JPEG' || file_suffix == 'PNG' || file_suffix == 'GIF') {
img = img + '<li><img data-original="img/tibet-'+i+'.jpg" src="'+ link + temp[1] +'" alt="'+temp[0] +'"></li>';
}
if (id == temp[1]) {
initialViewIndex = i;
}
}
}
img = '<ul>'+img + '</ul>';
div.innerHTML=img;
div.id='view-imgs';
var viewer = new Viewer(div, {
hidden: function() {
viewer.destroy();
},
toolbar: {
zoomIn: 3,
zoomOut: 3,
oneToOne: 3,
reset: 3,
prev: 3,
play: {
show: 3,
size: 'large',
},
next: 3,
rotateLeft: 3,
rotateRight: 3,
flipHorizontal: 3,
flipVertical: 3,
},
navbar:0,
});
//这个就是点开那张图片就是那张图片,从点开图片的那张开始
viewer.view(initialViewIndex);
//默认展示容器从第一张开始
//viewer.show();
}
//附件预览页面,图片点击事件
Ext.fly(document).on('click', function(ev){
//获取图片超链接
var target = ev.getTarget('a[ref=img]');
if (target) {
ev.preventDefault();//取消事件的默认动作。
//调用单张图片预览方法
//show_viewer_singer(target.href, target.title);
}
}, this);
function show_viewer_singer(src, name) {
var image = new Image();
image.src = src;
image.alt = name;
var viewer = new Viewer(image, {
hidden: function() {
viewer.destroy();
},
toolbar: {
zoomIn: 3,
zoomOut: 3,
oneToOne: 3,
reset: 3,
prev: 3,
play: {
show: 3,
size: 'large',
},
next: 3,
rotateLeft: 3,
rotateRight: 3,
flipHorizontal: 3,
flipVertical: 3,
},
});
viewer.show();
}
\ No newline at end of file
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment