@ -0,0 +1,121 @@ |
|||
import math |
|||
import queue |
|||
import cv2 |
|||
import threading |
|||
import time |
|||
from myutils.ConfigManager import myCongif |
|||
import subprocess as sp |
|||
|
|||
class VideoCaptureWithFPS: |
|||
'''视频捕获的封装类,是一个通道一个''' |
|||
def __init__(self, source): |
|||
self.source = source |
|||
self.width = None |
|||
self.height = None |
|||
# GStreamer --- 内存占用太高,且工作环境的部署也不简单 |
|||
# self.pipeline = ( |
|||
# "rtspsrc location=rtsp://192.168.3.102/live1 protocols=udp latency=100 ! " |
|||
# "rtph264depay !" |
|||
# " h264parse !" |
|||
# " avdec_h264 !" |
|||
# " videoconvert !" |
|||
# " appsink" |
|||
# ) |
|||
#self.cap = cv2.VideoCapture(self.pipeline, cv2.CAP_GSTREAMER) |
|||
|
|||
#FFmpeg --更加定制化的使用--但要明确宽高。。。 |
|||
# self.ffmpeg_cmd = [ |
|||
# 'ffmpeg', |
|||
# '-rtsp_transport', 'udp', |
|||
# '-i', 'rtsp://192.168.3.102/live1', |
|||
# '-f', 'image2pipe', |
|||
# '-pix_fmt', 'bgr24', |
|||
# '-vcodec', 'rawvideo', '-' |
|||
# ] |
|||
# self.pipe = sp.Popen(self.ffmpeg_cmd, stdout=sp.PIPE, bufsize=10 ** 8) |
|||
|
|||
# opencv -- 后端默认使用的就是FFmpeg -- 不支持UDP |
|||
self.cap = cv2.VideoCapture(self.source) |
|||
if self.cap.isOpened(): #若没有打开成功,在读取画面的时候,已有判断和处理 -- 这里也要检查下内存的释放情况 |
|||
self.width = int(self.cap.get(cv2.CAP_PROP_FRAME_WIDTH)) |
|||
self.height = int(self.cap.get(cv2.CAP_PROP_FRAME_HEIGHT)) |
|||
print(self.width,self.height) |
|||
#self.fps = fps # 线程保持最大帧率的刷新画面---过高的帧率会影响CPU性能,但过地的帧率会造成帧积压 |
|||
self.fps = math.ceil(self.cap.get(cv2.CAP_PROP_FPS)/float(myCongif.get_data("verify_rate")))-1 #向上取整。 |
|||
#print(self.fps) |
|||
self.running = True |
|||
self.frame_queue = queue.Queue(maxsize=1) |
|||
#self.frame = None |
|||
#self.read_lock = threading.Lock() |
|||
self.thread = threading.Thread(target=self.update) |
|||
self.thread.start() |
|||
|
|||
def update(self): |
|||
icount = 0 |
|||
while self.running: |
|||
ret, frame = self.cap.read() |
|||
if not ret: |
|||
icount += 1 |
|||
if icount > 5: #重连 |
|||
self.cap.release() |
|||
self.cap = cv2.VideoCapture(self.source) |
|||
#self.cap = cv2.VideoCapture(self.pipeline, cv2.CAP_GSTREAMER) |
|||
if self.cap.isOpened(): |
|||
self.width = int(self.cap.get(cv2.CAP_PROP_FRAME_WIDTH)) |
|||
self.height = int(self.cap.get(cv2.CAP_PROP_FRAME_HEIGHT)) |
|||
print(self.width,self.height) |
|||
# self.fps = fps # 线程保持最大帧率的刷新画面---过高的帧率会影响CPU性能,但过地的帧率会造成帧积压 |
|||
self.fps = math.ceil( |
|||
self.cap.get(cv2.CAP_PROP_FPS) / float(myCongif.get_data("verify_rate"))) -1 # 向上取整。 |
|||
icount = 0 |
|||
else: |
|||
#self.frame = None |
|||
sleep_time = myCongif.get_data("cap_sleep_time") |
|||
print(f"{self.source}视频流,将于{sleep_time}秒后重连!") |
|||
time.sleep(sleep_time) |
|||
continue |
|||
#resized_frame = cv2.resize(frame, (int(self.width / 2), int(self.height / 2))) |
|||
# with self.read_lock: |
|||
# self.frame = frame |
|||
if self.frame_queue.full(): |
|||
try: |
|||
#print("采集线程丢帧") |
|||
self.frame_queue.get(timeout=0.01) #这里不get的好处是,模型线程不会有None |
|||
except queue.Empty: #为空不处理 |
|||
pass |
|||
self.frame_queue.put(frame) |
|||
|
|||
# 跳过指定数量的帧以避免积压 |
|||
for _ in range(self.fps): |
|||
self.cap.grab() |
|||
# time.sleep(self.fps) #按照视频源的帧率进行休眠 |
|||
#print("Frame updated at:",time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())) |
|||
|
|||
def read(self): |
|||
''' |
|||
直接读视频原画面 |
|||
:param type: 0-大多数情况读取,1-绘制区域时读取一帧,但当前帧不丢,还是回队列 |
|||
:return: |
|||
''' |
|||
# with self.read_lock: |
|||
# frame = self.frame.copy() if self.frame is not None else None |
|||
# if frame is not None: |
|||
# return True, frame |
|||
# else: |
|||
# return False, None |
|||
|
|||
if not self.frame_queue.empty(): |
|||
try: |
|||
frame = self.frame_queue.get(timeout=0.05) |
|||
except queue.Empty: |
|||
#print("cap-frame None") |
|||
return False, None |
|||
else: |
|||
#print("cap-frame None") |
|||
return False, None |
|||
return True, frame |
|||
|
|||
def release(self): |
|||
self.running = False |
|||
self.thread.join() |
|||
self.cap.release() |
@ -1,204 +0,0 @@ |
|||
import torch |
|||
import cv2 |
|||
import numpy as np |
|||
import torch |
|||
import os |
|||
import importlib |
|||
from model.plugins.ModelBase import ModelBase |
|||
from loguru import logger |
|||
|
|||
''' |
|||
class ModelManager_tmp(): |
|||
def __init__(self): |
|||
print("ModelInit") |
|||
|
|||
def __del__(self): |
|||
print("ModelManager DEL") |
|||
|
|||
def __preprocess_image(self,image, cfg, bgr2rgb=True): |
|||
"""图片预处理""" |
|||
img, scale_ratio, pad_size = letterbox(image, new_shape=cfg['input_shape']) |
|||
if bgr2rgb: |
|||
img = img[:, :, ::-1] |
|||
img = img.transpose(2, 0, 1) # HWC2CHW |
|||
img = np.ascontiguousarray(img, dtype=np.float32) |
|||
return img, scale_ratio, pad_size |
|||
|
|||
def __draw_bbox(self,bbox, img0, color, wt, names): |
|||
"""在图片上画预测框""" |
|||
det_result_str = '' |
|||
for idx, class_id in enumerate(bbox[:, 5]): |
|||
if float(bbox[idx][4] < float(0.05)): |
|||
continue |
|||
img0 = cv2.rectangle(img0, (int(bbox[idx][0]), int(bbox[idx][1])), (int(bbox[idx][2]), int(bbox[idx][3])), |
|||
color, wt) |
|||
img0 = cv2.putText(img0, str(idx) + ' ' + names[int(class_id)], (int(bbox[idx][0]), int(bbox[idx][1] + 16)), |
|||
cv2.FONT_HERSHEY_SIMPLEX, 0.5, (0, 0, 255), 1) |
|||
img0 = cv2.putText(img0, '{:.4f}'.format(bbox[idx][4]), (int(bbox[idx][0]), int(bbox[idx][1] + 32)), |
|||
cv2.FONT_HERSHEY_SIMPLEX, 0.5, (0, 0, 255), 1) |
|||
det_result_str += '{} {} {} {} {} {}\n'.format( |
|||
names[bbox[idx][5]], str(bbox[idx][4]), bbox[idx][0], bbox[idx][1], bbox[idx][2], bbox[idx][3]) |
|||
return img0 |
|||
|
|||
def __get_labels_from_txt(self,path): |
|||
"""从txt文件获取图片标签""" |
|||
labels_dict = dict() |
|||
with open(path) as f: |
|||
for cat_id, label in enumerate(f.readlines()): |
|||
labels_dict[cat_id] = label.strip() |
|||
return labels_dict |
|||
|
|||
def __draw_prediction(self,pred, image, labels): |
|||
"""在图片上画出预测框并进行可视化展示""" |
|||
imgbox = widgets.Image(format='jpg', height=720, width=1280) |
|||
img_dw = self.__draw_bbox(pred, image, (0, 255, 0), 2, labels) |
|||
imgbox.value = cv2.imencode('.jpg', img_dw)[1].tobytes() |
|||
display(imgbox) |
|||
|
|||
def __infer_image(self,img_path, model, class_names, cfg): |
|||
"""图片推理""" |
|||
# 图片载入 |
|||
image = cv2.imread(img_path) |
|||
# 数据预处理 |
|||
img, scale_ratio, pad_size = self.__preprocess_image(image, cfg) |
|||
# 模型推理 |
|||
output = model.infer([img])[0] |
|||
|
|||
output = torch.tensor(output) |
|||
# 非极大值抑制后处理 |
|||
boxout = nms(output, conf_thres=cfg["conf_thres"], iou_thres=cfg["iou_thres"]) |
|||
pred_all = boxout[0].numpy() |
|||
# 预测坐标转换 |
|||
scale_coords(cfg['input_shape'], pred_all[:, :4], image.shape, ratio_pad=(scale_ratio, pad_size)) |
|||
# 图片预测结果可视化 |
|||
self.__draw_prediction(pred_all, image, class_names) |
|||
|
|||
def __infer_frame_with_vis(self,image, model, labels_dict, cfg, bgr2rgb=True): |
|||
# 数据预处理 |
|||
img, scale_ratio, pad_size = self.__preprocess_image(image, cfg, bgr2rgb) |
|||
# 模型推理 |
|||
output = model.infer([img])[0] |
|||
|
|||
output = torch.tensor(output) |
|||
# 非极大值抑制后处理 |
|||
boxout = nms(output, conf_thres=cfg["conf_thres"], iou_thres=cfg["iou_thres"]) |
|||
pred_all = boxout[0].numpy() |
|||
# 预测坐标转换 |
|||
scale_coords(cfg['input_shape'], pred_all[:, :4], image.shape, ratio_pad=(scale_ratio, pad_size)) |
|||
# 图片预测结果可视化 |
|||
img_vis = self.__draw_bbox(pred_all, image, (0, 255, 0), 2, labels_dict) |
|||
return img_vis |
|||
|
|||
def __img2bytes(self,image): |
|||
"""将图片转换为字节码""" |
|||
return bytes(cv2.imencode('.jpg', image)[1]) |
|||
def __infer_camera(self,model, labels_dict, cfg): |
|||
"""外设摄像头实时推理""" |
|||
|
|||
def find_camera_index(): |
|||
max_index_to_check = 10 # Maximum index to check for camera |
|||
|
|||
for index in range(max_index_to_check): |
|||
cap = cv2.VideoCapture(index) |
|||
if cap.read()[0]: |
|||
cap.release() |
|||
return index |
|||
|
|||
# If no camera is found |
|||
raise ValueError("No camera found.") |
|||
|
|||
# 获取摄像头 --这里可以换成RTSP流 |
|||
camera_index = find_camera_index() |
|||
cap = cv2.VideoCapture(camera_index) |
|||
# 初始化可视化对象 |
|||
image_widget = widgets.Image(format='jpeg', width=1280, height=720) |
|||
display(image_widget) |
|||
while True: |
|||
# 对摄像头每一帧进行推理和可视化 |
|||
_, img_frame = cap.read() |
|||
image_pred = self.__infer_frame_with_vis(img_frame, model, labels_dict, cfg) |
|||
image_widget.value = self.__img2bytes(image_pred) |
|||
|
|||
def __infer_video(self,video_path, model, labels_dict, cfg): |
|||
"""视频推理""" |
|||
image_widget = widgets.Image(format='jpeg', width=800, height=600) |
|||
display(image_widget) |
|||
|
|||
# 读入视频 |
|||
cap = cv2.VideoCapture(video_path) |
|||
while True: |
|||
ret, img_frame = cap.read() |
|||
if not ret: |
|||
break |
|||
# 对视频帧进行推理 |
|||
image_pred = self.__infer_frame_with_vis(img_frame, model, labels_dict, cfg, bgr2rgb=True) |
|||
image_widget.value = self.__img2bytes(image_pred) |
|||
|
|||
def startWork(self,infer_mode,file_paht = ""): |
|||
cfg = { |
|||
'conf_thres': 0.4, # 模型置信度阈值,阈值越低,得到的预测框越多 |
|||
'iou_thres': 0.5, # IOU阈值,高于这个阈值的重叠预测框会被过滤掉 |
|||
'input_shape': [640, 640], # 模型输入尺寸 |
|||
} |
|||
|
|||
model_path = 'yolo.om' |
|||
label_path = './coco_names.txt' |
|||
# 初始化推理模型 |
|||
model = InferSession(0, model_path) |
|||
labels_dict = self.__get_labels_from_txt(label_path) |
|||
|
|||
#执行验证 |
|||
if infer_mode == 'image': |
|||
img_path = 'world_cup.jpg' |
|||
self.__infer_image(img_path, model, labels_dict, cfg) |
|||
elif infer_mode == 'camera': |
|||
self.__infer_camera(model, labels_dict, cfg) |
|||
elif infer_mode == 'video': |
|||
video_path = 'racing.mp4' |
|||
self.__infer_video(video_path, model, labels_dict, cfg) |
|||
''' |
|||
|
|||
''' |
|||
算法实现类,实现算法执行线程,根据配内容,以线程方式执行算法模块 |
|||
''' |
|||
class ModelManager(): |
|||
def __init__(self): |
|||
print("ModelManager init") |
|||
|
|||
def __del__(self): |
|||
print("ModelManager del") |
|||
|
|||
def doWork(self): |
|||
pass |
|||
|
|||
#动态导入文件 -- 方法二 -- 相对推荐使用该方法 但spec感觉没什么用 |
|||
def import_source(spec, plgpath): |
|||
module = None |
|||
if os.path.exists(plgpath): |
|||
module_spec = importlib.util.spec_from_file_location(spec, plgpath) |
|||
module = importlib.util.module_from_spec(module_spec) |
|||
module_spec.loader.exec_module(module) |
|||
else: |
|||
logger.error("{}文件不存在".format(plgpath)) |
|||
return module |
|||
|
|||
#plgpath 为list [poc][file_name][name] |
|||
def run_plugin(plgpath, target,copy_flag=True): |
|||
module = import_source("", plgpath) |
|||
if module: |
|||
classname = "Model" |
|||
plg = getattr(module, classname)() |
|||
if not isinstance(plg, ModelBase): |
|||
raise Exception("{} not rx_Model".format(plg)) |
|||
new_plg = plg |
|||
result = new_plg.doWork("","","","") # 执行plugin基类的run, 返回结果 |
|||
return result |
|||
else: |
|||
print("模型加载失败") |
|||
return None |
|||
|
|||
def test(): |
|||
run_plugin("plugins/RYRQ_Model_ACL.py","") |
|||
|
|||
if __name__ == "__main__": |
|||
test() |
@ -1,9 +0,0 @@ |
|||
from model.plugins.ModelBase import ModelBase |
|||
|
|||
class Model(ModelBase): |
|||
def __init__(self): |
|||
super().__init__() |
|||
pass |
|||
|
|||
def doWork(self,image,mode,class_name,cfg,isdraw_box=False,bgr2rgb=True): |
|||
print("AQM_Model") |
@ -1,155 +0,0 @@ |
|||
# 导入代码依赖 |
|||
import cv2 |
|||
import numpy as np |
|||
from myutils.ConfigManager import myCongif |
|||
import os |
|||
import torch |
|||
|
|||
import ipywidgets as widgets |
|||
from IPython.display import display |
|||
from skvideo.io import vreader, FFmpegWriter |
|||
import IPython.display |
|||
from ais_bench.infer.interface import InferSession |
|||
from det_utils import letterbox, scale_coords, nms |
|||
|
|||
def preprocess_image(image, cfg, bgr2rgb=True): |
|||
"""图片预处理""" |
|||
img, scale_ratio, pad_size = letterbox(image, new_shape=cfg['input_shape']) |
|||
if bgr2rgb: |
|||
img = img[:, :, ::-1] |
|||
img = img.transpose(2, 0, 1) # HWC2CHW |
|||
img = np.ascontiguousarray(img, dtype=np.float32) |
|||
return img, scale_ratio, pad_size |
|||
|
|||
def draw_bbox(bbox, img0, color, wt, names): |
|||
"""在图片上画预测框""" |
|||
det_result_str = '' |
|||
for idx, class_id in enumerate(bbox[:, 5]): |
|||
if float(bbox[idx][4] < float(0.05)): |
|||
continue |
|||
img0 = cv2.rectangle(img0, (int(bbox[idx][0]), int(bbox[idx][1])), (int(bbox[idx][2]), int(bbox[idx][3])), |
|||
color, wt) |
|||
img0 = cv2.putText(img0, str(idx) + ' ' + names[int(class_id)], (int(bbox[idx][0]), int(bbox[idx][1] + 16)), |
|||
cv2.FONT_HERSHEY_SIMPLEX, 0.5, (0, 0, 255), 1) |
|||
img0 = cv2.putText(img0, '{:.4f}'.format(bbox[idx][4]), (int(bbox[idx][0]), int(bbox[idx][1] + 32)), |
|||
cv2.FONT_HERSHEY_SIMPLEX, 0.5, (0, 0, 255), 1) |
|||
det_result_str += '{} {} {} {} {} {}\n'.format( |
|||
names[bbox[idx][5]], str(bbox[idx][4]), bbox[idx][0], bbox[idx][1], bbox[idx][2], bbox[idx][3]) |
|||
return img0 |
|||
|
|||
def get_labels_from_txt(path): |
|||
"""从txt文件获取图片标签""" |
|||
labels_dict = dict() |
|||
with open(path) as f: |
|||
for cat_id, label in enumerate(f.readlines()): |
|||
labels_dict[cat_id] = label.strip() |
|||
return labels_dict |
|||
|
|||
def draw_prediction(pred, image, labels): |
|||
"""在图片上画出预测框并进行可视化展示""" |
|||
imgbox = widgets.Image(format='jpg', height=720, width=1280) |
|||
img_dw = draw_bbox(pred, image, (0, 255, 0), 2, labels) |
|||
imgbox.value = cv2.imencode('.jpg', img_dw)[1].tobytes() |
|||
display(imgbox) |
|||
|
|||
def infer_image(img_path, model, class_names, cfg): |
|||
"""图片推理""" |
|||
# 图片载入 |
|||
image = cv2.imread(img_path) |
|||
# 数据预处理 |
|||
img, scale_ratio, pad_size = preprocess_image(image, cfg) |
|||
# 模型推理 |
|||
output = model.infer([img])[0] |
|||
|
|||
output = torch.tensor(output) |
|||
# 非极大值抑制后处理 |
|||
boxout = nms(output, conf_thres=cfg["conf_thres"], iou_thres=cfg["iou_thres"]) |
|||
pred_all = boxout[0].numpy() |
|||
# 预测坐标转换 |
|||
scale_coords(cfg['input_shape'], pred_all[:, :4], image.shape, ratio_pad=(scale_ratio, pad_size)) |
|||
# 图片预测结果可视化 |
|||
draw_prediction(pred_all, image, class_names) |
|||
|
|||
def infer_frame_with_vis(image, model, labels_dict, cfg, bgr2rgb=True): |
|||
# 数据预处理 |
|||
img, scale_ratio, pad_size = preprocess_image(image, cfg, bgr2rgb) |
|||
# 模型推理 |
|||
output = model.infer([img])[0] |
|||
|
|||
output = torch.tensor(output) |
|||
# 非极大值抑制后处理 |
|||
boxout = nms(output, conf_thres=cfg["conf_thres"], iou_thres=cfg["iou_thres"]) |
|||
pred_all = boxout[0].numpy() |
|||
# 预测坐标转换 |
|||
scale_coords(cfg['input_shape'], pred_all[:, :4], image.shape, ratio_pad=(scale_ratio, pad_size)) |
|||
# 图片预测结果可视化 |
|||
img_vis = draw_bbox(pred_all, image, (0, 255, 0), 2, labels_dict) |
|||
return img_vis |
|||
|
|||
def img2bytes(image): |
|||
"""将图片转换为字节码""" |
|||
return bytes(cv2.imencode('.jpg', image)[1]) |
|||
|
|||
def infer_video(video_path, model, labels_dict, cfg): |
|||
"""视频推理""" |
|||
image_widget = widgets.Image(format='jpeg', width=800, height=600) |
|||
display(image_widget) |
|||
|
|||
# 读入视频 |
|||
cap = cv2.VideoCapture(video_path) |
|||
while True: |
|||
ret, img_frame = cap.read() |
|||
if not ret: |
|||
break |
|||
# 对视频帧进行推理 |
|||
image_pred = infer_frame_with_vis(img_frame, model, labels_dict, cfg, bgr2rgb=True) |
|||
image_widget.value = img2bytes(image_pred) |
|||
|
|||
def infer_camera(model, labels_dict, cfg): |
|||
"""外设摄像头实时推理""" |
|||
def find_camera_index(): |
|||
max_index_to_check = 10 # Maximum index to check for camera |
|||
|
|||
for index in range(max_index_to_check): |
|||
cap = cv2.VideoCapture(index) |
|||
if cap.read()[0]: |
|||
cap.release() |
|||
return index |
|||
|
|||
# If no camera is found |
|||
raise ValueError("No camera found.") |
|||
|
|||
# 获取摄像头 |
|||
camera_index = find_camera_index() |
|||
cap = cv2.VideoCapture(camera_index) |
|||
# 初始化可视化对象 |
|||
image_widget = widgets.Image(format='jpeg', width=1280, height=720) |
|||
display(image_widget) |
|||
while True: |
|||
# 对摄像头每一帧进行推理和可视化 |
|||
_, img_frame = cap.read() |
|||
image_pred = infer_frame_with_vis(img_frame, model, labels_dict, cfg) |
|||
image_widget.value = img2bytes(image_pred) |
|||
|
|||
if __name__ == "__main__": |
|||
cfg = { |
|||
'conf_thres': 0.4, # 模型置信度阈值,阈值越低,得到的预测框越多 |
|||
'iou_thres': 0.5, # IOU阈值,高于这个阈值的重叠预测框会被过滤掉 |
|||
'input_shape': [640, 640], # 模型输入尺寸 |
|||
} |
|||
model_path = os.path.join(myCongif.get_data('weight_path'),'/yolov5-1/yolov5s.pt') |
|||
label_path = os.path.join(myCongif.get_data('weight_path'),'/yolov5-1/coco_names.txt') |
|||
# 初始化推理模型 |
|||
model = InferSession(0, model_path) |
|||
labels_dict = get_labels_from_txt(label_path) |
|||
|
|||
infer_mode = 'video' |
|||
|
|||
if infer_mode == 'image': |
|||
img_path = 'world_cup.jpg' |
|||
infer_image(img_path, model, labels_dict, cfg) |
|||
elif infer_mode == 'camera': |
|||
infer_camera(model, labels_dict, cfg) |
|||
elif infer_mode == 'video': |
|||
video_path = 'racing.mp4' |
|||
infer_video(video_path, model, labels_dict, cfg) |
@ -1,64 +0,0 @@ |
|||
import torch |
|||
import cv2 |
|||
import numpy as np |
|||
from shapely.geometry import Point, Polygon |
|||
import os |
|||
|
|||
# # 自定义模型文件的路径 |
|||
# model_path = 'yolov5s.pt' # 假设模型文件名为 yolov5s.pt 并与执行文件在同一个目录 |
|||
# # 本地YOLOv5仓库路径 |
|||
# repo_path = '../base_model/yolov5' |
|||
# 自定义模型文件的路径 |
|||
print(f"Current working directory (yolov5.py): {os.getcwd()}") |
|||
model_path = 'D:/Project/FristProject/model/mode_test/yolov5s.pt' # 假设模型文件名为 yolov5s.pt 并与执行文件在同一个目录 |
|||
# 本地YOLOv5仓库路径 |
|||
repo_path = 'D:/Project/FristProject/model/base_model/yolov5' |
|||
|
|||
# 加载自定义模型 |
|||
model = torch.hub.load(repo_path, 'custom', path=model_path, source='local') |
|||
|
|||
# 定义监控区域(多边形顶点) |
|||
region_points = [(100, 100), (500, 100), (500, 400), (100, 400)] |
|||
polygon = Polygon(region_points) |
|||
|
|||
# 打开摄像头 |
|||
cap = cv2.VideoCapture(0) |
|||
|
|||
def is_point_in_polygon(point, polygon): |
|||
return polygon.contains(Point(point)) |
|||
|
|||
while True: |
|||
ret, frame = cap.read() |
|||
if not ret: |
|||
break |
|||
|
|||
# 进行推理 |
|||
results = model(frame) |
|||
detections = results.pandas().xyxy[0] |
|||
|
|||
# 绘制监控区域 |
|||
cv2.polylines(frame, [np.array(region_points, np.int32)], isClosed=True, color=(0, 255, 0), thickness=2) |
|||
|
|||
for _, row in detections.iterrows(): |
|||
if row['name'] == 'person': |
|||
# 获取人员检测框的中心点 |
|||
x_center = (row['xmin'] + row['xmax']) / 2 |
|||
y_center = (row['ymin'] + row['ymax']) / 2 |
|||
|
|||
if is_point_in_polygon((x_center, y_center), polygon): |
|||
# 触发报警 |
|||
cv2.putText(frame, 'Alert: Intrusion Detected', (50, 50), cv2.FONT_HERSHEY_SIMPLEX, 1, (0, 0, 255), 2) |
|||
print('Alert: Intrusion Detected') |
|||
|
|||
# 绘制检测框 |
|||
cv2.rectangle(frame, (int(row['xmin']), int(row['ymin'])), (int(row['xmax']), int(row['ymax'])), (255, 0, 0), 2) |
|||
cv2.circle(frame, (int(x_center), int(y_center)), 5, (0, 0, 255), -1) |
|||
|
|||
# 显示结果 |
|||
cv2.imshow('Frame', frame) |
|||
|
|||
if cv2.waitKey(1) & 0xFF == ord('q'): |
|||
break |
|||
|
|||
cap.release() |
|||
cv2.destroyAllWindows() |
@ -0,0 +1,300 @@ |
|||
import subprocess |
|||
import platform |
|||
import locale |
|||
import re |
|||
|
|||
''' |
|||
针对windows和linux的网络信息获取和设置功能类。 |
|||
由于网络接口名字并不一定,又有多网卡等情况,实际应用时需要指定网络接口(固化硬件环境) |
|||
''' |
|||
|
|||
class IPManager: |
|||
def __init__(self): |
|||
self.os_type = platform.system() |
|||
self.encoding = locale.getpreferredencoding() |
|||
|
|||
def set_ip(self, interface_name, ip_address, subnet_mask, gateway): |
|||
if self.os_type == "Windows": |
|||
self._set_ip_windows(interface_name, ip_address, subnet_mask, gateway) |
|||
elif self.os_type == "Linux": |
|||
self._set_ip_linux(interface_name, ip_address, subnet_mask, gateway) |
|||
else: |
|||
raise NotImplementedError("Unsupported OS") |
|||
|
|||
def connect_wifi(self, ssid, password): |
|||
if self.os_type == "Windows": |
|||
self._connect_wifi_windows(ssid, password) |
|||
elif self.os_type == "Linux": |
|||
self._connect_wifi_linux(ssid, password) |
|||
else: |
|||
raise NotImplementedError("Unsupported OS") |
|||
|
|||
def get_wifi_list(self): |
|||
wifis = [] |
|||
if self.os_type == "Windows": |
|||
wifis = self._get_wifi_list_windows() |
|||
elif self.os_type == "Linux": |
|||
wifis = self._get_wifi_list_linux() |
|||
else: |
|||
raise NotImplementedError("Unsupported OS") |
|||
return wifis |
|||
|
|||
def get_connected_wifi(self): |
|||
ssid = None |
|||
if self.os_type == "Windows": |
|||
ssid = self._get_connected_wifi_windows() |
|||
elif self.os_type == "Linux": |
|||
ssid = self._get_connected_wifi_linux() |
|||
else: |
|||
raise NotImplementedError("Unsupported OS") |
|||
return ssid |
|||
|
|||
def get_network_info(self): |
|||
info = None |
|||
if self.os_type == "Windows": |
|||
info = self._get_network_info_windows() |
|||
elif self.os_type == "Linux": |
|||
info = self._get_network_info_linux() |
|||
else: |
|||
raise NotImplementedError("Unsupported OS") |
|||
return info |
|||
|
|||
def _set_ip_windows(self, interface_name, ip_address, subnet_mask, gateway): |
|||
command = f'netsh interface ip set address name="{interface_name}" static {ip_address} {subnet_mask} {gateway} 1' |
|||
#result = subprocess.run(command, shell=True,capture_output=True, text=True, encoding='utf-8') |
|||
# 打印输出结果 |
|||
result = self._run_cmd(command) |
|||
print(result.stdout) |
|||
|
|||
# 检查返回码 |
|||
if result.returncode == 0: |
|||
print("IP address set successfully.") |
|||
else: |
|||
print("Failed to set IP address. Please check the output for errors.") |
|||
|
|||
def _set_ip_linux(self, interface_name, ip_address, subnet_mask, gateway): |
|||
self._run_cmd(f"sudo ip addr flush dev {interface_name}") |
|||
self._run_cmd(f"sudo ip addr add {ip_address}/{subnet_mask} dev {interface_name}") |
|||
self._run_cmd(f"sudo ip route add default via {gateway}") |
|||
|
|||
def _connect_wifi_windows(self, ssid, password): |
|||
command = f'netsh wlan connect name="{ssid}"' |
|||
self._run_cmd(command) |
|||
|
|||
def _connect_wifi_linux(self, ssid, password): |
|||
command = f"nmcli dev wifi connect '{ssid}' password '{password}'" |
|||
self._run_cmd(command) |
|||
|
|||
def _get_wifi_list_windows(self): |
|||
command = "netsh wlan show networks" |
|||
result = self._run_cmd(command) |
|||
wifi_list = [] |
|||
lines = result.stdout.split('\n') |
|||
for line in lines: |
|||
if "SSID" in line and "BSSID" not in line: |
|||
ssid = line.split(":")[1].strip() |
|||
wifi_list.append(ssid) |
|||
|
|||
return wifi_list |
|||
|
|||
def _get_wifi_list_linux(self): |
|||
command = "nmcli dev wifi list" |
|||
result = self._run_cmd(command) |
|||
|
|||
# 解析输出结果 |
|||
wifi_list = [] |
|||
lines = result.stdout.split('\n') |
|||
for line in lines[1:]: # 跳过表头 |
|||
if line.strip(): |
|||
ssid = line.split()[0] |
|||
wifi_list.append(ssid) |
|||
|
|||
return wifi_list |
|||
|
|||
def _get_connected_wifi_windows(self): |
|||
command = "netsh wlan show interfaces" |
|||
result = self._run_cmd(command) |
|||
|
|||
# 使用正则表达式提取SSID |
|||
ssid_match = re.search(r"SSID\s+: (.+)", result.stdout) |
|||
|
|||
if ssid_match: |
|||
ssid = ssid_match.group(1).strip() |
|||
return ssid |
|||
else: |
|||
return None |
|||
|
|||
def _get_connected_wifi_linux(self): |
|||
command = "iwgetid -r" |
|||
result = self._run_cmd(command) |
|||
|
|||
ssid = result.stdout.strip() |
|||
if ssid: |
|||
return ssid |
|||
else: |
|||
return None |
|||
|
|||
def _get_network_info_windows(self): |
|||
command = "ipconfig /all" |
|||
result = self._run_cmd(command) |
|||
|
|||
interfaces = {} |
|||
current_interface = None |
|||
for line in result.stdout.splitlines(): |
|||
# 识别接口名称 |
|||
interface_match = re.match(r"^\s*([^:\s]+.*):$", line) |
|||
if interface_match: |
|||
current_interface = interface_match.group(1).strip() |
|||
interfaces[current_interface] = {"IP": None, "Subnet": None, "Gateway": None, "DNS": []} |
|||
|
|||
if current_interface: |
|||
# 解析IP地址 |
|||
ip_match = re.search(r"^\s*IPv4 地址[^\:]*:\s*(\d+\.\d+\.\d+\.\d+)", line) |
|||
if ip_match: |
|||
interfaces[current_interface]["IP"] = ip_match.group(1).strip() |
|||
|
|||
# 解析子网掩码 |
|||
subnet_match = re.search(r"^\s*子网掩码[^\:]*:\s*(\d+\.\d+\.\d+\.\d+)", line) |
|||
if subnet_match: |
|||
interfaces[current_interface]["Subnet"] = subnet_match.group(1).strip() |
|||
|
|||
# 解析网关 |
|||
gateway_match = re.search(r"^\s*默认网关[^\:]*:\s*(\d+\.\d+\.\d+\.\d+)", line) |
|||
if gateway_match: |
|||
interfaces[current_interface]["Gateway"] = gateway_match.group(1).strip() |
|||
|
|||
# 解析DNS服务器 |
|||
dns_match = re.search(r"^\s*DNS 服务器[^\:]*:\s*(\d+\.\d+\.\d+\.\d+)", line) |
|||
if dns_match: |
|||
interfaces[current_interface]["DNS"].append(dns_match.group(1).strip()) |
|||
else: |
|||
# 匹配后续行的DNS服务器 |
|||
dns_continued_match = re.search(r"^\s*(\d+\.\d+\.\d+\.\d+)", line) |
|||
if dns_continued_match: |
|||
interfaces[current_interface]["DNS"].append(dns_continued_match.group(1).strip()) |
|||
return interfaces |
|||
|
|||
def _get_network_info_linux(self): |
|||
# 获取IP地址、子网掩码和网关 |
|||
ip_info = self._run_cmd("ip addr show").stdout |
|||
route_info = self._run_cmd("ip route show").stdout |
|||
|
|||
# 获取DNS服务器 |
|||
dns_info = self._run_cmd("nmcli dev show | grep DNS").stdout |
|||
|
|||
interfaces = {} |
|||
current_interface = None |
|||
for line in ip_info.splitlines(): |
|||
# 识别接口名称 |
|||
interface_match = re.match(r"^\d+: ([^:\s]+):", line) |
|||
if interface_match: |
|||
current_interface = interface_match.group(1).strip() |
|||
interfaces[current_interface] = {"IP": None, "Subnet": None, "Gateway": None, "DNS": []} |
|||
|
|||
if current_interface: |
|||
# 解析IP地址和子网掩码 |
|||
ip_match = re.search(r"^\s*inet (\d+\.\d+\.\d+\.\d+)/(\d+)", line) |
|||
if ip_match: |
|||
interfaces[current_interface]["IP"] = ip_match.group(1).strip() |
|||
interfaces[current_interface]["Subnet"] = ip_match.group(2).strip() |
|||
|
|||
# 解析网关 |
|||
for line in route_info.splitlines(): |
|||
if "default via" in line: |
|||
gateway_match = re.search(r"default via (\d+\.\d+\.\d+\.\d+)", line) |
|||
interface_match = re.search(r"dev (\S+)", line) |
|||
if gateway_match and interface_match: |
|||
interface = interface_match.group(1).strip() |
|||
if interface in interfaces: |
|||
interfaces[interface]["Gateway"] = gateway_match.group(1).strip() |
|||
|
|||
# 解析DNS服务器 |
|||
for line in dns_info.splitlines(): |
|||
dns_match = re.search(r"DNS\[\d+\]:\s*(\d+\.\d+\.\d+\.\d+)", line) |
|||
if dns_match: |
|||
# 假设第一个接口是主要接口 |
|||
primary_interface = list(interfaces.keys())[0] |
|||
interfaces[primary_interface]["DNS"].append(dns_match.group(1).strip()) |
|||
|
|||
return interfaces |
|||
|
|||
def _get_interface_info_windows(self,interface_name): |
|||
command = f'netsh interface ip show config name="{interface_name}"' |
|||
result = self._run_cmd(command) |
|||
|
|||
info = {"IP": None, "Subnet": None, "Gateway": None, "DNS": []} |
|||
|
|||
# 解析IP地址 |
|||
ip_match = re.search(r"IP Address:\s*(\d+\.\d+\.\d+\.\d+)", result.stdout) |
|||
if ip_match: |
|||
info["IP"] = ip_match.group(1).strip() |
|||
|
|||
# 解析子网掩码 |
|||
subnet_match = re.search(r"Subnet Prefix:\s*(\d+\.\d+\.\d+\.\d+)", result.stdout) |
|||
if subnet_match: |
|||
info["Subnet"] = subnet_match.group(1).strip() |
|||
|
|||
# 解析网关 |
|||
gateway_match = re.search(r"Default Gateway:\s*(\d+\.\d+\.\d+\.\d+)", result.stdout) |
|||
if gateway_match: |
|||
info["Gateway"] = gateway_match.group(1).strip() |
|||
|
|||
# 解析DNS服务器 |
|||
dns_matches = re.findall(r"Statically Configured DNS Servers:\s*(\d+\.\d+\.\d+\.\d+)", result.stdout) |
|||
for dns in dns_matches: |
|||
info["DNS"].append(dns.strip()) |
|||
|
|||
return info |
|||
|
|||
def _get_interface_info_linux(self,interface_name): |
|||
info = {"IP": None, "Subnet": None, "Gateway": None, "DNS": []} |
|||
|
|||
# 获取IP地址和子网掩码 |
|||
ip_command = f"ip addr show dev {interface_name}" |
|||
ip_result = self._run_cmd(ip_command) |
|||
|
|||
ip_match = re.search(r"inet (\d+\.\d+\.\d+\.\d+)/(\d+)", ip_result.stdout) |
|||
if ip_match: |
|||
info["IP"] = ip_match.group(1).strip() |
|||
info["Subnet"] = ip_match.group(2).strip() |
|||
|
|||
# 获取网关信息 |
|||
gateway_command = f"ip route show dev {interface_name}" |
|||
gateway_result = subprocess.run(gateway_command, shell=True, capture_output=True, text=True, encoding='utf-8') |
|||
|
|||
gateway_match = re.search(r"default via (\d+\.\d+\.\d+\.\d+)", gateway_result.stdout) |
|||
if gateway_match: |
|||
info["Gateway"] = gateway_match.group(1).strip() |
|||
|
|||
# 获取DNS服务器信息 |
|||
dns_command = f"nmcli dev show {interface_name} | grep DNS" |
|||
dns_result = subprocess.run(dns_command, shell=True, capture_output=True, text=True, encoding='utf-8') |
|||
|
|||
dns_matches = re.findall(r"DNS\[\d+\]:\s*(\d+\.\d+\.\d+\.\d+)", dns_result.stdout) |
|||
for dns in dns_matches: |
|||
info["DNS"].append(dns.strip()) |
|||
|
|||
return info |
|||
|
|||
def _run_cmd(self,command): |
|||
''' |
|||
为了统一命令执行的返回参数格式,统一定义了一个执行函数 |
|||
:param command: |
|||
:return: |
|||
''' |
|||
result = subprocess.run(command, shell=True, capture_output=True, text=True, encoding=self.encoding) |
|||
return result |
|||
|
|||
IPM = IPManager() |
|||
|
|||
if __name__ == "__main__":#WLAN |
|||
# 示例用法 |
|||
nm = IPManager() |
|||
try: |
|||
#nm.set_ip("以太网 2", "192.168.1.100", "255.255.255.0", "192.168.1.1") |
|||
#nm.set_ip("WLAN", "192.168.3.100", "255.255.255.0", "192.168.3.1") #zhang wifi |
|||
network_info = nm.get_wifi_list() |
|||
print(network_info) |
|||
except Exception as e: |
|||
print(e) |
|||
#nm.connect_wifi("YourSSID", "YourPassword") |
Before Width: | Height: | Size: 9.8 KiB |
Before Width: | Height: | Size: 3.4 KiB |
@ -1,187 +0,0 @@ |
|||
<html> |
|||
<head> |
|||
<title>Install the Axure RP Chrome Extension</title> |
|||
<style type="text/css"> |
|||
* |
|||
{ |
|||
font-family: NunitoSans, Helvetica, Arial, sans-serif; |
|||
} |
|||
body |
|||
{ |
|||
text-align: center; |
|||
background-color: #fafafa; |
|||
} |
|||
p |
|||
{ |
|||
font-size: 14px; |
|||
line-height: 18px; |
|||
color: #333333; |
|||
} |
|||
div.container |
|||
{ |
|||
width: 980px; |
|||
margin-left: auto; |
|||
margin-right: auto; |
|||
text-align: left; |
|||
} |
|||
a |
|||
{ |
|||
text-decoration: none; |
|||
color: #009dda; |
|||
} |
|||
.button |
|||
{ |
|||
background: #A502B3; |
|||
font: normal 16px Arial, sans-serif; |
|||
color: #FFFFFF; |
|||
padding: 10px 30px 10px 30px; |
|||
border: 2px solid #A502B3; |
|||
display: inline-block; |
|||
margin-top: 10px; |
|||
text-transform: uppercase; |
|||
font-size: 14px; |
|||
border-radius: 4px; |
|||
} |
|||
a:hover.button |
|||
{ |
|||
border: 2px solid #A502B3; |
|||
color: #A502B3; |
|||
background-color: #FFFFFF; |
|||
} |
|||
div.left |
|||
{ |
|||
width: 400px; |
|||
float: left; |
|||
margin-right: 80px; |
|||
} |
|||
div.right |
|||
{ |
|||
width: 400px; |
|||
float: left; |
|||
} |
|||
div.buttonContainer |
|||
{ |
|||
text-align: center; |
|||
} |
|||
h1 |
|||
{ |
|||
font-size: 36px; |
|||
color: #333333; |
|||
line-height: 50px; |
|||
margin-bottom: 20px; |
|||
font-weight: normal; |
|||
} |
|||
h2 |
|||
{ |
|||
font-size: 24px; |
|||
font-weight: normal; |
|||
color: #08639C; |
|||
text-align: center; |
|||
} |
|||
h3 |
|||
{ |
|||
font-size: 16px; |
|||
color: #333333; |
|||
font-weight: normal; |
|||
text-transform: uppercase; |
|||
} |
|||
.heading |
|||
{ |
|||
border-bottom: 1px solid black; |
|||
height: 36px; |
|||
line-height: 36px; |
|||
font-size: 22px; |
|||
color: #000000; |
|||
|
|||
} |
|||
span.faq |
|||
{ |
|||
font-size: 16px; |
|||
line-height: 24px; |
|||
font-weight: normal; |
|||
text-transform: uppercase; |
|||
color: #333333; |
|||
display: block; |
|||
} |
|||
</style> |
|||
</head> |
|||
<body> |
|||
<div class="container"> |
|||
<br /> |
|||
<br /> |
|||
<img src="axure_logo.png" alt="axure" /> |
|||
<br /> |
|||
<br /> |
|||
<h1> |
|||
AXURE RP EXTENSION FOR CHROME</h1> |
|||
<p style="font-size: 14px; color: #666666; margin-top: 10px;"> |
|||
Google Chrome requires an extension to view locally stored projects. Alternatively, |
|||
upload your RP file to <a href="https://www.axure.cloud">Axure Cloud</a> or use a different |
|||
browser. You can also Preview from Axure RP.</p> |
|||
<img src="preview-rp.png" alt="preview"/> |
|||
<h3 class="heading"> |
|||
VIEW LOCAL PROJECTS IN CHROME</h3> |
|||
<div class="left"> |
|||
<h3> |
|||
1. Install Extension from Chrome Store</h3> |
|||
<div class="buttonContainer"> |
|||
<a class="button" href="https://chrome.google.com/webstore/detail/dogkpdfcklifaemcdfbildhcofnopogp" |
|||
target="_blank">Install Extension</a> |
|||
</div> |
|||
</div> |
|||
<div class="right"> |
|||
<h3> |
|||
2. Open "More Tools > Extensions"</h3> |
|||
<img src="extensions.png" alt="extensions"/> |
|||
</div> |
|||
<div style="clear: both; height: 20px;"> |
|||
</div> |
|||
<div class="left"> |
|||
<h3> |
|||
3. View Axure RP Extension Details</h3> |
|||
<img src="details.png" alt="extension details"/> |
|||
</div> |
|||
<div class="right"> |
|||
<h3> |
|||
4. Check "Allow access to file URLs"</h3> |
|||
<img src="allow-access.png" alt="allow access"/> |
|||
</div> |
|||
<div style="clear: both; height: 20px;"> |
|||
</div> |
|||
<div class="left"> |
|||
<h3> |
|||
5. Click the button below</h3> |
|||
<div class="buttonContainer"> |
|||
<a class="button" href="../../start.html">View in Chrome</a> |
|||
</div> |
|||
</div> |
|||
<div style="clear: both; height: 20px;"> |
|||
</div> |
|||
<h3 class="heading"> |
|||
EXTENSION FAQ</h3> |
|||
<p> |
|||
<span class="faq">What is a Chrome Extension?</span> Extensions are downloadable |
|||
plug-ins for Google Chrome that modify the browser |
|||
and allow you additional capabilities. |
|||
</p> |
|||
<p style="margin-top: 25px;"> |
|||
<span class="faq">Why do I need to install the extension?</span> Google requires |
|||
this extension to be installed to allow the viewing of local files in |
|||
Chrome |
|||
</p> |
|||
<p style="margin-top: 25px; margin-bottom: 25px;"> |
|||
<span class="faq">Why does this extension require a high access level?</span> This |
|||
extension requires a high access level to allow the viewing of the file:// |
|||
protocol. Axure does not track or access any of your information. |
|||
</p> |
|||
<h3 class="heading"> |
|||
WE'RE HERE TO HELP</h3> |
|||
<p> |
|||
Need help or have any questions? Contact our support team at <a href="mailto:support@axure.com"> |
|||
support@axure.com</a>. |
|||
</p> |
|||
<div style="clear: both; height: 20px;"> |
|||
</div> |
|||
</div> |
|||
</body> |
|||
</html> |
Before Width: | Height: | Size: 21 KiB |
Before Width: | Height: | Size: 38 KiB |
@ -1,130 +0,0 @@ |
|||
<html> |
|||
<head> |
|||
<title>Axure RP - Firefox Local File Restrictions</title> |
|||
<style type="text/css"> |
|||
* |
|||
{ |
|||
font-family: Helvetica, Arial, sans-serif; |
|||
} |
|||
body |
|||
{ |
|||
text-align: center; |
|||
background-color: #fafafa; |
|||
} |
|||
p |
|||
{ |
|||
font-size: 14px; |
|||
line-height: 18px; |
|||
color: #333333; |
|||
} |
|||
div.container |
|||
{ |
|||
width: 980px; |
|||
margin-left: auto; |
|||
margin-right: auto; |
|||
text-align: left; |
|||
} |
|||
a |
|||
{ |
|||
text-decoration: none; |
|||
color: #009dda; |
|||
} |
|||
.button |
|||
{ |
|||
background: #A502B3; |
|||
font: normal 16px Arial, sans-serif; |
|||
color: #FFFFFF; |
|||
padding: 10px 30px 10px 30px; |
|||
border: 2px solid #A502B3; |
|||
display: inline-block; |
|||
margin-top: 10px; |
|||
text-transform: uppercase; |
|||
font-size: 14px; |
|||
border-radius: 4px; |
|||
} |
|||
a:hover.button |
|||
{ |
|||
border: 2px solid #A502B3; |
|||
color: #A502B3; |
|||
background-color: #FFFFFF; |
|||
} |
|||
div.left |
|||
{ |
|||
width: 400px; |
|||
float: left; |
|||
margin-right: 80px; |
|||
} |
|||
div.right |
|||
{ |
|||
width: 400px; |
|||
float: left; |
|||
} |
|||
div.buttonContainer |
|||
{ |
|||
text-align: center; |
|||
} |
|||
h1 |
|||
{ |
|||
font-size: 36px; |
|||
color: #333333; |
|||
line-height: 50px; |
|||
margin-bottom: 20px; |
|||
font-weight: normal; |
|||
} |
|||
h2 |
|||
{ |
|||
font-size: 24px; |
|||
font-weight: normal; |
|||
color: #08639C; |
|||
text-align: center; |
|||
} |
|||
h3 |
|||
{ |
|||
font-size: 16px; |
|||
line-height: 24px; |
|||
color: #333333; |
|||
font-weight: normal; |
|||
} |
|||
.heading |
|||
{ |
|||
border-bottom: 1px solid black; |
|||
height: 36px; |
|||
line-height: 36px; |
|||
font-size: 22px; |
|||
color: #000000; |
|||
} |
|||
span.faq |
|||
{ |
|||
font-size: 16px; |
|||
font-weight: normal; |
|||
text-transform: uppercase; |
|||
color: #333333; |
|||
display: block; |
|||
} |
|||
</style> |
|||
</head> |
|||
<body> |
|||
<div class="container"> |
|||
<br /> |
|||
<br /> |
|||
<img src="axure_logo.png" alt="axure" /> |
|||
<br /> |
|||
<h1> |
|||
FIREFOX LOCAL FILE RESTRICTIONS</h1> |
|||
<p style="font-size: 16px; line-height: 24px; color: #666666; margin-top: 10px;"> |
|||
Firefox does not permit locally stored files to be viewed. Use Preview to view your projects in progress. |
|||
<img src="preview-rp.png" alt="preview"/> |
|||
</p> |
|||
<p style="font-size: 16px; line-height: 24px; color: #666666; margin-top: 10px;"> |
|||
Alternatively, you can choose a different web browser, upload your RP file to <a href="https://app.axure.cloud">Axure Cloud</a> or publish the local files to a web server.</p> |
|||
<h3 class="heading"> |
|||
We're Here to Help</h3> |
|||
<p> |
|||
Need help or have any questions? Drop us a line at <a href="mailto:support@axure.com"> |
|||
support@axure.com</a>. |
|||
</p> |
|||
<div style="clear: both; height: 20px;"> |
|||
</div> |
|||
</div> |
|||
</body> |
|||
</html> |
Before Width: | Height: | Size: 21 KiB |
@ -1,155 +0,0 @@ |
|||
<html> |
|||
<head> |
|||
<title>Axure RP - Safari Local File Restrictions</title> |
|||
<style type="text/css"> |
|||
* |
|||
{ |
|||
font-family: Helvetica, Arial, sans-serif; |
|||
} |
|||
body |
|||
{ |
|||
text-align: center; |
|||
background-color: #fafafa; |
|||
} |
|||
p |
|||
{ |
|||
font-size: 14px; |
|||
line-height: 18px; |
|||
color: #333333; |
|||
} |
|||
div.container |
|||
{ |
|||
width: 980px; |
|||
margin-left: auto; |
|||
margin-right: auto; |
|||
text-align: left; |
|||
} |
|||
a |
|||
{ |
|||
text-decoration: none; |
|||
color: #009dda; |
|||
} |
|||
.button |
|||
{ |
|||
background: #A502B3; |
|||
font: normal 16px Arial, sans-serif; |
|||
color: #FFFFFF; |
|||
padding: 10px 30px 10px 30px; |
|||
border: 2px solid #A502B3; |
|||
display: inline-block; |
|||
margin-top: 10px; |
|||
text-transform: uppercase; |
|||
font-size: 14px; |
|||
border-radius: 4px; |
|||
} |
|||
a:hover.button |
|||
{ |
|||
border: 2px solid #A502B3; |
|||
color: #A502B3; |
|||
background-color: #FFFFFF; |
|||
} |
|||
div.left |
|||
{ |
|||
width: 400px; |
|||
float: left; |
|||
margin-right: 80px; |
|||
} |
|||
div.right |
|||
{ |
|||
width: 400px; |
|||
float: left; |
|||
} |
|||
div.buttonContainer |
|||
{ |
|||
text-align: center; |
|||
} |
|||
h1 |
|||
{ |
|||
font-size: 36px; |
|||
color: #333333; |
|||
line-height: 50px; |
|||
margin-bottom: 20px; |
|||
font-weight: normal; |
|||
} |
|||
h2 |
|||
{ |
|||
font-size: 24px; |
|||
font-weight: normal; |
|||
color: #08639C; |
|||
text-align: center; |
|||
} |
|||
h3 |
|||
{ |
|||
font-size: 16px; |
|||
line-height: 24px; |
|||
color: #333333; |
|||
font-weight: normal; |
|||
} |
|||
.heading |
|||
{ |
|||
border-bottom: 1px solid black; |
|||
height: 36px; |
|||
line-height: 36px; |
|||
font-size: 22px; |
|||
color: #000000; |
|||
} |
|||
span.faq |
|||
{ |
|||
font-size: 16px; |
|||
font-weight: normal; |
|||
text-transform: uppercase; |
|||
color: #333333; |
|||
display: block; |
|||
} |
|||
</style> |
|||
</head> |
|||
<body> |
|||
<div class="container"> |
|||
<br /> |
|||
<br /> |
|||
<img src="axure_logo.png" alt="axure" /> |
|||
<br /> |
|||
<h1> |
|||
SAFARI LOCAL FILE RESTRICTIONS</h1> |
|||
<p style="font-size: 16px; line-height: 24px; color: #666666; margin-top: 10px;"> |
|||
To view locally stored projects in Safari, you will need to "disable local file restrictions". Alternatively, |
|||
you can upload your RP file to <a href="https://www.axure.cloud">Axure Cloud</a> or publish the local files to a web server. You can also Preview from Axure RP.</p> |
|||
<img src="preview-rp.png" alt="preview"/> |
|||
<h3 class="heading"> |
|||
VIEW LOCAL PROJECTS IN SAFARI</h3> |
|||
<div class=""> |
|||
<h3> |
|||
1. Open "Safari > Preferences > Advanced" from the top menu, and check the option to "Show Develop menu in menu bar"</h3> |
|||
<img src="safari_advanced.png" alt="advanced" /> |
|||
</div> |
|||
<div style="clear: both; height: 20px;"> |
|||
|
|||
</div> |
|||
<div class=""> |
|||
<h3> |
|||
2. In the Develop menu that appears in the menu bar, click "Develop > Disable Local File Restrictions" to un-select the menu option</h3> |
|||
<img src="safari_restrictions.png" alt="extensions" /> |
|||
</div> |
|||
<div style="clear: both; height: 20px;"> |
|||
</div> |
|||
<div class="left"> |
|||
<h3> |
|||
3. Click the button below |
|||
</h3> |
|||
<div class="buttonContainer"> |
|||
<a class="button" href="../../start.html">View in Safari</a> |
|||
</div> |
|||
</div> |
|||
<div style="clear: both; height: 20px;"> |
|||
</div> |
|||
<h3 class="heading"> |
|||
We're Here to Help</h3> |
|||
<p> |
|||
Need help or have any questions? Drop us a line at <a href="mailto:support@axure.com"> |
|||
support@axure.com</a>. |
|||
</p> |
|||
<div style="clear: both; height: 20px;"> |
|||
</div> |
|||
</div> |
|||
</body> |
|||
</html> |
Before Width: | Height: | Size: 83 KiB |
Before Width: | Height: | Size: 149 KiB |
Before Width: | Height: | Size: 1.2 KiB |
Before Width: | Height: | Size: 251 B |
@ -1,771 +0,0 @@ |
|||
$axure.internal(function($ax) { |
|||
$ax.adaptive = {}; |
|||
|
|||
$axure.utils.makeBindable($ax.adaptive, ["viewChanged"]); |
|||
|
|||
var _auto = true; |
|||
var _autoIsHandledBySidebar = false; |
|||
|
|||
var _views; |
|||
var _idToView; |
|||
var _enabledViews = []; |
|||
|
|||
var _initialViewToLoad; |
|||
var _initialViewSizeToLoad; |
|||
|
|||
var _loadFinished = false; |
|||
$ax.adaptive.loadFinished = function() { |
|||
if(_loadFinished) return; |
|||
_loadFinished = true; |
|||
if($ax.adaptive.currentViewId) $ax.viewChangePageAndMasters(); |
|||
else $ax.postAdaptiveViewChanged(); |
|||
}; |
|||
|
|||
var _handleResize = function(forceSwitchTo) { |
|||
if(!_auto) return; |
|||
if(_auto && _autoIsHandledBySidebar && !forceSwitchTo) return; |
|||
|
|||
var $window = $(window); |
|||
var height = $window.height(); |
|||
var width = $window.width(); |
|||
|
|||
var toView = _getAdaptiveView(width, height); |
|||
var toViewId = toView && toView.id; |
|||
|
|||
_switchView(toViewId, forceSwitchTo); |
|||
}; |
|||
|
|||
var _setAuto = $ax.adaptive.setAuto = function(val) { |
|||
if(_auto != val) { |
|||
_auto = Boolean(val); |
|||
} |
|||
}; |
|||
|
|||
var _setLineImage = function(id, imageUrl) { |
|||
$jobj(id).attr('src', imageUrl); |
|||
}; |
|||
|
|||
var _switchView = function (viewId, forceSwitchTo) { |
|||
//if(!$ax.pageData.isAdaptiveEnabled) return;
|
|||
|
|||
var previousViewId = $ax.adaptive.currentViewId; |
|||
if(typeof previousViewId == 'undefined') previousViewId = ''; |
|||
if(typeof viewId == 'undefined') viewId = ''; |
|||
if (viewId == previousViewId) { |
|||
if(forceSwitchTo) $ax.postAdaptiveViewChanged(forceSwitchTo); |
|||
return; |
|||
} |
|||
|
|||
$ax('*').each(function(obj, elementId) { |
|||
if (!$ax.public.fn.IsTreeNodeObject(obj.type)) return; |
|||
if(!obj.hasOwnProperty('isExpanded')) return; |
|||
|
|||
var query = $ax('#' + elementId); |
|||
var defaultExpanded = obj.isExpanded; |
|||
|
|||
query.expanded(defaultExpanded); |
|||
}); |
|||
|
|||
// reset all the inline positioning from move and rotate actions including size and transformation
|
|||
$axure('*').each(function (diagramObject, elementId) { |
|||
if(diagramObject.isContained) return; |
|||
if($ax.getParentRepeaterFromElementIdExcludeSelf(elementId)) return; |
|||
|
|||
var element = document.getElementById(elementId); |
|||
if(element) { |
|||
var resetCss = { |
|||
top: "", left: "", width: "", height: "", opacity: "", |
|||
transform: "", webkitTransform: "", MozTransform: "", msTransform: "", OTransform: "" |
|||
}; |
|||
var query = $(element); |
|||
query.css(resetCss); |
|||
var isPanel = $ax.public.fn.IsDynamicPanel(diagramObject.type); |
|||
if(!isPanel || diagramObject.fitToContent) { //keeps size on the panel states when switching adaptive views to optimize fit to panel
|
|||
if(diagramObject.fitToContent) $ax.dynamicPanelManager.setFitToContentCss(elementId, true); |
|||
var children = query.children(); |
|||
if(children.length) children.css(resetCss); |
|||
} |
|||
|
|||
$ax.dynamicPanelManager.resetFixedPanel(diagramObject, element); |
|||
$ax.dynamicPanelManager.resetAdaptivePercentPanel(diagramObject, element); |
|||
} |
|||
}); |
|||
|
|||
$ax.adaptive.currentViewId = viewId; // we need to set this so the enabled and selected styles will apply properly
|
|||
if(previousViewId) { |
|||
$ax.style.clearAdaptiveStyles(); |
|||
$('*').removeClass(previousViewId); |
|||
} else { |
|||
$ax.style.reselectElements(); |
|||
} |
|||
|
|||
$axure('*').each(function (obj, elementId) { |
|||
if($ax.getParentRepeaterFromElementIdExcludeSelf(elementId)) return; |
|||
|
|||
$ax.style.updateElementIdImageStyle(elementId); // When image override exists, fix styling/borders
|
|||
}); |
|||
|
|||
//$ax.style.startSuspendTextAlignment();
|
|||
|
|||
// reset all the images only if we're going back to the default view
|
|||
if(!viewId) { |
|||
$axure('*').each(function (diagramObject, elementId) { |
|||
if($ax.getParentRepeaterFromElementIdExcludeSelf(elementId)) return; |
|||
|
|||
$ax.placeholderManager.refreshPlaceholder(elementId); |
|||
|
|||
var images = diagramObject.images; |
|||
if(diagramObject.type == 'horizontalLine' || diagramObject.type == 'verticalLine') { |
|||
var startImg = images['start~']; |
|||
_setLineImage(elementId + "_start", startImg); |
|||
var endImg = images['end~']; |
|||
_setLineImage(elementId + "_end", endImg); |
|||
var lineImg = images['line~']; |
|||
_setLineImage(elementId + "_line", lineImg); |
|||
} else if(diagramObject.type == $ax.constants.CONNECTOR_TYPE) { |
|||
_setAdaptiveConnectorImages(elementId, images, ''); |
|||
} else if(images) { |
|||
if (diagramObject.generateCompound) { |
|||
|
|||
if($ax.style.IsWidgetDisabled(elementId)) { |
|||
disabledImage = _getImageWithTag(images, 'disabled~'); |
|||
if(disabledImage) $ax.style.applyImage(elementId, disabledImage, 'disabled'); |
|||
return; |
|||
} |
|||
if($ax.style.IsWidgetSelected(elementId)) { |
|||
selectedImage = _getImageWithTag(images, 'selected~'); |
|||
if(selectedImage) $ax.style.applyImage(elementId, selectedImage, 'selected'); |
|||
return; |
|||
} |
|||
$ax.style.applyImage(elementId, _getImageWithTag(images, 'normal~'), 'normal'); |
|||
} else { |
|||
if ($ax.style.IsWidgetDisabled(elementId)) { |
|||
var disabledImage = _matchImage(elementId, images, [], 'disabled', true); |
|||
if (disabledImage) $ax.style.applyImage(elementId, disabledImage, 'disabled'); |
|||
return; |
|||
} |
|||
if ($ax.style.IsWidgetSelected(elementId)) { |
|||
var selectedImage = _matchImage(elementId, images, [], 'selected', true); |
|||
if (selectedImage) $ax.style.applyImage(elementId, selectedImage, 'selected'); |
|||
return; |
|||
} |
|||
var normalImage = _matchImage(elementId, images, [], 'normal', true); |
|||
$ax.style.applyImage(elementId, normalImage, 'normal'); |
|||
} |
|||
} |
|||
|
|||
//align all text
|
|||
var child = $jobj(elementId).children('.text'); |
|||
if(child.length) $ax.style.transformTextWithVerticalAlignment(child[0].id, function() { }); |
|||
}); |
|||
// we have to reset visibility if we aren't applying a new view
|
|||
$ax.visibility.resetLimboAndHiddenToDefaults(); |
|||
$ax.visibility.clearMovedAndResized(); |
|||
$ax.repeater.refreshAllRepeaters(); |
|||
$ax.dynamicPanelManager.updateParentsOfNonDefaultFitPanels(); |
|||
$ax.dynamicPanelManager.updatePercentPanelCache($ax('*')); |
|||
} else { |
|||
$ax.visibility.clearLimboAndHidden(); |
|||
$ax.visibility.clearMovedAndResized(); |
|||
_applyView(viewId); |
|||
$ax.repeater.refreshAllRepeaters(); |
|||
$ax.dynamicPanelManager.updateAllLayerSizeCaches(); |
|||
$ax.dynamicPanelManager.updateParentsOfNonDefaultFitPanels(); |
|||
} |
|||
|
|||
$ax.annotation.updateAllFootnotes(); |
|||
//$ax.style.resumeSuspendTextAlignment();
|
|||
|
|||
$ax.adaptive.triggerEvent('viewChanged', {}); |
|||
if(_loadFinished) $ax.viewChangePageAndMasters(forceSwitchTo); |
|||
}; |
|||
|
|||
var _getImageWithTag = function(image, tag) { |
|||
var flattened = {}; |
|||
for (var component in image) { |
|||
var componentImage = image[component][tag]; |
|||
if(componentImage) flattened[component] = componentImage; |
|||
} |
|||
return flattened; |
|||
} |
|||
|
|||
// gets the inheritance chain of a particular view.
|
|||
var _getAdaptiveIdChain = $ax.adaptive.getAdaptiveIdChain = function(viewId) { |
|||
if(!viewId) return []; |
|||
var view = _idToView[viewId]; |
|||
var chain = []; |
|||
var current = view; |
|||
while(current) { |
|||
chain[chain.length] = current.id; |
|||
current = _idToView[current.baseViewId]; |
|||
} |
|||
return chain.reverse(); |
|||
}; |
|||
|
|||
var _getMasterAdaptiveIdChain = $ax.adaptive.getMasterAdaptiveIdChain = function (masterId, viewId) { |
|||
if (!viewId) return []; |
|||
|
|||
var master = $ax.pageData.masters[masterId]; |
|||
var masterViews = master.adaptiveViews; |
|||
var idToMasterView = {}; |
|||
if (masterViews && masterViews.length > 0) { |
|||
for (var i = 0; i < masterViews.length; i++) { |
|||
var view = masterViews[i]; |
|||
idToMasterView[view.id] = view; |
|||
} |
|||
} |
|||
|
|||
if (!idToMasterView) return []; |
|||
|
|||
var view = idToMasterView[viewId]; |
|||
var chain = []; |
|||
var current = view; |
|||
while (current) { |
|||
chain[chain.length] = current.id; |
|||
current = idToMasterView[current.baseViewId]; |
|||
} |
|||
return chain.reverse(); |
|||
}; |
|||
|
|||
var _getPageStyle = $ax.adaptive.getPageStyle = function() { |
|||
var currentViewId = $ax.adaptive.currentViewId; |
|||
var adaptiveChain = _getAdaptiveIdChain(currentViewId); |
|||
|
|||
var currentStyle = $.extend({}, $ax.pageData.page.style); |
|||
for(var i = 0; i < adaptiveChain.length; i++) { |
|||
var viewId = adaptiveChain[i]; |
|||
$.extend(currentStyle, $ax.pageData.page.adaptiveStyles[viewId]); |
|||
} |
|||
|
|||
return currentStyle; |
|||
}; |
|||
|
|||
var _setAdaptiveLineImages = function(elementId, images, viewIdChain) { |
|||
for(var i = viewIdChain.length - 1; i >= 0; i--) { |
|||
var viewId = viewIdChain[i]; |
|||
var startImg = images['start~' + viewId]; |
|||
if(startImg) { |
|||
_setLineImage(elementId + "_start", startImg); |
|||
var endImg = images['end~' + viewId]; |
|||
_setLineImage(elementId + "_end", endImg); |
|||
var lineImg = images['line~' + viewId]; |
|||
_setLineImage(elementId + "_line", lineImg); |
|||
break; |
|||
} |
|||
} |
|||
}; |
|||
|
|||
var _setAdaptiveConnectorImages = function (elementId, images, view) { |
|||
var conn = $jobj(elementId); |
|||
var count = conn.children().length-1; // -1 for rich text panel
|
|||
for(var i = 0; i < count; i++) { |
|||
var img = images['' + i + '~' + view]; |
|||
$jobj(elementId + '_seg' + i).attr('src', img); |
|||
} |
|||
}; |
|||
|
|||
var _applyView = $ax.adaptive.applyView = function(viewId, query) { |
|||
var limboIds = {}; |
|||
var hiddenIds = {}; |
|||
|
|||
var jquery; |
|||
if(query) { |
|||
jquery = query.jQuery(); |
|||
jquery = jquery.add(jquery.find('*')); |
|||
var jqueryAnn = $ax.annotation.jQueryAnn(query); |
|||
jquery = jquery.add(jqueryAnn); |
|||
} else { |
|||
jquery = $('*').not('#ios-safari-fixed'); |
|||
query = $ax('*'); |
|||
} |
|||
jquery.addClass(viewId); |
|||
var viewIdChain = _getAdaptiveIdChain(viewId); |
|||
// this could be made more efficient by computing it only once per object
|
|||
query.each(function(diagramObject, elementId) { |
|||
_applyAdaptiveViewOnObject(diagramObject, elementId, viewIdChain, viewId, limboIds, hiddenIds); |
|||
}); |
|||
|
|||
$ax.visibility.addLimboAndHiddenIds(limboIds, hiddenIds, query); |
|||
//$ax.dynamicPanelManager.updateAllFitPanelsAndLayerSizeCaches();
|
|||
$ax.dynamicPanelManager.updatePercentPanelCache(query); |
|||
}; |
|||
|
|||
var _applyAdaptiveViewOnObject = function(diagramObject, elementId, viewIdChain, viewId, limboIds, hiddenIds) { |
|||
var adaptiveChain = []; |
|||
for(var i = 0; i < viewIdChain.length; i++) { |
|||
var viewId = viewIdChain[i]; |
|||
var viewStyle = diagramObject.adaptiveStyles[viewId]; |
|||
if(viewStyle) { |
|||
adaptiveChain[adaptiveChain.length] = viewStyle; |
|||
if (viewStyle.size) $ax.public.fn.convertToSingleImage($jobj(elementId)); |
|||
} |
|||
} |
|||
|
|||
var state = $ax.style.generateState(elementId); |
|||
|
|||
// set the image
|
|||
var images = diagramObject.images; |
|||
if(images) { |
|||
if(diagramObject.type == 'horizontalLine' || diagramObject.type == 'verticalLine') { |
|||
_setAdaptiveLineImages(elementId, images, viewIdChain); |
|||
} else if (diagramObject.type == $ax.constants.CONNECTOR_TYPE) { |
|||
_setAdaptiveConnectorImages(elementId, images, viewId); |
|||
} else if (diagramObject.generateCompound) { |
|||
var compoundUrl = _matchImageCompound(diagramObject, elementId, viewIdChain, state); |
|||
if (compoundUrl) $ax.style.applyImage(elementId, compoundUrl, state); |
|||
}else { |
|||
var imgUrl = _matchImage(elementId, images, viewIdChain, state); |
|||
if(imgUrl) $ax.style.applyImage(elementId, imgUrl, state); |
|||
} |
|||
} |
|||
// addaptive override style (not including default style props)
|
|||
var adaptiveStyle = $ax.style.computeAllOverrides(elementId, undefined, state, viewId); |
|||
|
|||
// this style INCLUDES the object's my style
|
|||
var compoundStyle = $.extend({}, diagramObject.style, adaptiveStyle); |
|||
|
|||
// if (diagramObject.owner.type == 'Axure:Master' && diagramObject.adaptiveStyles) {
|
|||
// adaptiveStyle = $ax.style.computeFullStyle(elementId, state, viewId);
|
|||
// }
|
|||
|
|||
if(!diagramObject.isContained) { |
|||
$ax.style.setAdaptiveStyle(elementId, adaptiveStyle); |
|||
} |
|||
|
|||
var scriptId = $ax.repeater.getScriptIdFromElementId(elementId); |
|||
if(compoundStyle.limbo && !diagramObject.isContained) limboIds[scriptId] = true; |
|||
// sigh, javascript. we need the === here because undefined means not overriden
|
|||
if(compoundStyle.visible === false) hiddenIds[scriptId] = true; |
|||
}; |
|||
|
|||
var _matchImage = function(id, images, viewIdChain, state, doNotProgress) { |
|||
var override = $ax.style.getElementImageOverride(id, state); |
|||
if(override) return override; |
|||
|
|||
if(!images) return undefined; |
|||
|
|||
let scriptId = $ax.repeater.getScriptIdFromElementId(id); |
|||
|
|||
if(state == 'disabled' && $ax.style.IsWidgetSelected(id) || state == 'selected' && $ax.style.IsWidgetDisabled(id)) { |
|||
let diagramObject = $ax.getObjectFromElementId(id); |
|||
if(diagramObject && $ax.public.fn.IsSelectionButton(diagramObject.type)) { |
|||
var selectedDisabled = $ax.constants.SELECTED_DISABLED; |
|||
} |
|||
} |
|||
|
|||
// first check all the images for this state
|
|||
for(let i = viewIdChain.length - 1; i >= 0; i--) { |
|||
let viewId = viewIdChain[i]; |
|||
if(selectedDisabled) { |
|||
let img = findImage(images, scriptId, selectedDisabled, viewId) |
|||
if(img) return img; |
|||
} else { |
|||
let img = findImage(images, scriptId, state, viewId); |
|||
if (img) return img; |
|||
} |
|||
} |
|||
// check for the default state style
|
|||
if(selectedDisabled) { |
|||
let defaultStateImage = findImage(images, scriptId, selectedDisabled) |
|||
if(defaultStateImage) return defaultStateImage; |
|||
} else { |
|||
let defaultStateImage = findImage(images, scriptId, state); |
|||
if (defaultStateImage) return defaultStateImage; |
|||
} |
|||
|
|||
if(doNotProgress) return undefined; |
|||
|
|||
state = $ax.style.progessState(state); |
|||
if (state) return _matchImage(scriptId, images, viewIdChain, state); |
|||
|
|||
// SHOULD NOT REACH HERE! NORMAL SHOULD ALWAYS CATCH AT THE DEFAULT!
|
|||
return images['normal~']; // this is the default
|
|||
}; |
|||
|
|||
let findImage = function(images, scriptId, state, viewId) { |
|||
if(!images) return undefined; |
|||
|
|||
if(!viewId) viewId = ""; |
|||
let withScript = scriptId + "~" + state + "~" + viewId; |
|||
let img = images[withScript]; |
|||
if(!img) img = images[state + "~" + viewId]; |
|||
return img; |
|||
} |
|||
|
|||
var _matchImageCompound = function(diagramObject, id, viewIdChain, state) { |
|||
var images = []; |
|||
for(var i = 0; i < diagramObject.compoundChildren.length; i++) { |
|||
var component = diagramObject.compoundChildren[i]; |
|||
images[component] = _matchImage(id, diagramObject.images[component], viewIdChain, state); |
|||
} |
|||
return images; |
|||
}; |
|||
|
|||
|
|||
|
|||
$ax.adaptive.getImageForStateAndView = function(id, state) { |
|||
var viewIdChain = _getAdaptiveIdChain($ax.adaptive.currentViewId); |
|||
var diagramObject = $ax.getObjectFromElementId(id); |
|||
if (diagramObject.generateCompound) return _matchImageCompound(diagramObject, id, viewIdChain, state); |
|||
else return _matchImage(id, diagramObject.images, viewIdChain, state); |
|||
}; |
|||
|
|||
var _getAdaptiveView = function(winWidth, winHeight) { |
|||
var _isViewOneGreaterThanTwo = function (view1, view2, winHeight) { |
|||
if (view1.size.width > view2.size.width) return true; |
|||
if (view1.size.width == view2.size.width) { |
|||
if (view2.size.height <= winHeight) return view1.size.height > view2.size.height && view1.size.height <= winHeight; |
|||
else return view1.size.height < view2.size.height; |
|||
} |
|||
return false; |
|||
}; |
|||
|
|||
var _isViewOneLessThanTwo = function(view1, view2) { |
|||
var width2 = view2.size.width || 1000000; // artificially large number
|
|||
var height2 = view2.size.height || 1000000; |
|||
|
|||
var width1 = view1.size.width || 1000000; |
|||
var height1 = view1.size.height || 1000000; |
|||
|
|||
return width1 < width2 || (width1 == width2 && height1 < height2); |
|||
}; |
|||
|
|||
var _isWindowWidthGreaterThanViewWidth = function(view, width) { |
|||
return width >= view.size.width; |
|||
}; |
|||
|
|||
var _isWindowWidthLessThanViewWidth = function(view1, width) { |
|||
var viewWidth = view1.size.width || 1000000; |
|||
|
|||
return width <= viewWidth; |
|||
}; |
|||
|
|||
var greater = undefined; |
|||
var less = undefined; |
|||
|
|||
var defaultView = $ax.pageData.defaultAdaptiveView; |
|||
if (_isWindowWidthGreaterThanViewWidth(defaultView, winWidth, winHeight)) greater = defaultView; |
|||
less = defaultView; |
|||
for(var i = 0; i < _enabledViews.length; i++) { |
|||
var view = _enabledViews[i]; |
|||
if(_isWindowWidthGreaterThanViewWidth(view, winWidth, winHeight)) { |
|||
if(!greater || _isViewOneGreaterThanTwo(view, greater, winHeight)) greater = view; |
|||
} |
|||
if(_isWindowWidthLessThanViewWidth(view, winWidth, winHeight)) { |
|||
if(!less || _isViewOneLessThanTwo(view, less)) less = view; |
|||
} |
|||
} |
|||
return greater || less; |
|||
}; |
|||
|
|||
var _isAdaptiveInitialized = function() { |
|||
return typeof _idToView != 'undefined'; |
|||
}; |
|||
|
|||
|
|||
$ax.messageCenter.addMessageListener(function(message, data) { |
|||
//If the adaptive plugin hasn't been initialized yet then
|
|||
//save the view to load so that it can get set when initialize occurs
|
|||
if (message == 'switchAdaptiveView') { |
|||
if (!$axure.utils.isInPlayer()) return; |
|||
|
|||
var href = window.location.href.split('#')[0]; |
|||
var lastSlash = href.lastIndexOf('/'); |
|||
href = href.substring(lastSlash + 1); |
|||
if(href != data.src) return; |
|||
|
|||
var view = data.view == 'auto' ? undefined : (data.view == 'default' ? '' : data.view); |
|||
|
|||
if(!_isAdaptiveInitialized()) { |
|||
_initialViewToLoad = view; |
|||
} else _handleLoadViewId(view); |
|||
} else if (message == 'setAdaptiveViewForSize') { |
|||
if (!$axure.utils.isInPlayer()) return; |
|||
|
|||
_autoIsHandledBySidebar = true; |
|||
if(!_isAdaptiveInitialized()) { |
|||
_initialViewSizeToLoad = data; |
|||
} else _handleSetViewForSize(data.width, data.height); |
|||
} else if (message == 'getScale') { |
|||
if (!$axure.utils.isInPlayer()) return; |
|||
|
|||
var prevScaleN = data.prevScaleN; |
|||
var newScaleN = 1; |
|||
var contentOriginOffset = 0; |
|||
|
|||
var $body = $('body'); |
|||
$body.css('height', ''); |
|||
|
|||
if (data.scale != 0) { |
|||
var adjustScrollScale = false; |
|||
if ($('html').getNiceScroll().length == 0 && !MOBILE_DEVICE) { |
|||
//adding nicescroll so width is correct when getting scale
|
|||
_addNiceScroll($('html'), { emulatetouch: false, horizrailenabled: false }); |
|||
adjustScrollScale = true; |
|||
} |
|||
|
|||
$('html').css('overflow-x', 'hidden'); |
|||
|
|||
var bodyWidth = $body.width(); |
|||
var isCentered = $body.css('position') == 'relative'; |
|||
|
|||
// screen width does not adjust on screen rotation for iOS (width is always shorter screen measurement)
|
|||
var isLandscape = window.orientation != 0 && window.orientation != 180; |
|||
var mobileWidth = (IOS ? (isLandscape ? window.screen.height : window.screen.width) : window.screen.width) - data.panelWidthOffset; |
|||
var scaleN = newScaleN = (MOBILE_DEVICE ? mobileWidth : $(window).width()) / bodyWidth; |
|||
|
|||
if (data.scale == 2) { |
|||
var pageSize = $ax.public.fn.getPageSize(); |
|||
var hScaleN = (MOBILE_DEVICE ? data.viewportHeight : $(window).height()) / Math.max(1, pageSize.bottom); |
|||
if (hScaleN < scaleN) { |
|||
scaleN = newScaleN = hScaleN; |
|||
} |
|||
if (isCentered) contentOriginOffset = scaleN * (bodyWidth / 2); |
|||
} |
|||
|
|||
if ((SAFARI && IOS) || SHARE_APP) { |
|||
var pageSize = $ax.public.fn.getPageSize(); |
|||
$body.first().css('height', pageSize.bottom + 'px'); |
|||
} //else $body.css('height', $body.height() + 'px');
|
|||
|
|||
if (adjustScrollScale) { |
|||
_removeNiceScroll($('html')); |
|||
_addNiceScroll($('html'), { emulatetouch: false, horizrailenabled: false, cursorwidth: Math.ceil(6 / newScaleN) + 'px', cursorborder: 1 / newScaleN + 'px solid #fff', cursorborderradius: 5 / newScaleN + 'px' }); |
|||
} |
|||
} |
|||
var contentScale = { |
|||
scaleN: newScaleN, |
|||
prevScaleN: prevScaleN, |
|||
contentOriginOffset: contentOriginOffset, |
|||
clipToView: data.clipToView, |
|||
viewportHeight: data.viewportHeight, |
|||
viewportWidth: data.viewportWidth, |
|||
panelWidthOffset: data.panelWidthOffset, |
|||
scale: data.scale |
|||
}; |
|||
$axure.messageCenter.postMessage('setContentScale', contentScale); |
|||
|
|||
} else if (message == 'setDeviceMode') { |
|||
if (!$axure.utils.isInPlayer()) return; |
|||
|
|||
_isDeviceMode = data.device; |
|||
if (data.device) { |
|||
// FIXES firefox cursor not staying outside initial device frame border
|
|||
// SAFARI needs entire content height so that trackpad can be disabled
|
|||
//if (FIREFOX || (SAFARI && !IOS)) {
|
|||
// var pageSize = $ax.public.fn.getPageSize();
|
|||
// $('html').css('height', pageSize.bottom + 'px');
|
|||
//}
|
|||
|
|||
_removeNiceScroll($('html'), true); |
|||
if (!MOBILE_DEVICE) { |
|||
_addNiceScroll($('html'), { emulatetouch: true, horizrailenabled: false }, true); |
|||
$('html').addClass('mobileFrameCursor'); |
|||
$('html').css('cursor', 'url(resources/css/images/touch.cur), auto'); |
|||
$('html').css('cursor', 'url(resources/css/images/touch.svg) 32 32, auto'); |
|||
$('html').css('overflow-x', 'hidden'); |
|||
|
|||
if (IE) { |
|||
document.addEventListener("click", function () { |
|||
// IE still sometimes wants an argument here
|
|||
this.activeElement.releasePointerCapture(); |
|||
}, false); |
|||
} |
|||
|
|||
if ($axure.browser.isEdge) { |
|||
document.addEventListener("pointerdown", function (e) { |
|||
this.activeElement.releasePointerCapture(e.pointerId); |
|||
}, false); |
|||
} |
|||
|
|||
$ax.dynamicPanelManager.initMobileScroll(); |
|||
} |
|||
|
|||
// Gives horizontal scroll to android in 100% (handled outside of iframe)
|
|||
$('html').css('overflow-x', 'hidden'); |
|||
$('body').css('margin', '0px'); |
|||
$(function () { _setHorizontalScroll(false); }); |
|||
} else { |
|||
_removeNiceScroll($('html'), true); |
|||
$('html').css('overflow-x', ''); |
|||
$('html').css('cursor', ''); |
|||
//$('html').removeAttr('style');
|
|||
$('body').css('margin', ''); |
|||
$('html').removeClass('mobileFrameCursor'); |
|||
$(function () { _setHorizontalScroll(!data.scaleToWidth); }); |
|||
|
|||
$ax.dynamicPanelManager.initMobileScroll(); |
|||
} |
|||
} |
|||
}); |
|||
|
|||
var _isDeviceMode = false; |
|||
$ax.adaptive.isDeviceMode = function () { |
|||
return _isDeviceMode; |
|||
} |
|||
|
|||
var _isHtmlQuery = function ($container) { return $container.length > 0 && $container[0] == $('html')[0]; } |
|||
|
|||
var _removeNiceScroll = $ax.adaptive.removeNiceScroll = function ($container, blockResetScroll) { |
|||
if (!blockResetScroll) { |
|||
$container.scrollLeft(0); |
|||
$container.scrollTop(0); |
|||
} |
|||
var nS = $container.getNiceScroll(); |
|||
var emulateTouch = nS.length > 0 && nS[0].opt.emulateTouch; |
|||
nS.remove(); |
|||
//clean up nicescroll css
|
|||
if (IE) $container.css({ '-ms-overflow-y': '', 'overflow-y': '', '-ms-overflow-style': '', '-ms-touch-action': '' }); |
|||
if (!emulateTouch) return; |
|||
if (_isHtmlQuery($container)) { |
|||
$('#scrollContainer').remove(); |
|||
$('#base').off('mouseleave.ax'); |
|||
} else { |
|||
$container.off('mouseleave.ax'); |
|||
} |
|||
} |
|||
|
|||
var _addNiceScrollExitDetector = function ($container) { |
|||
if (_isHtmlQuery($container)) { |
|||
|
|||
// add a fixed div the size of the frame that will not move as we scroll like html,body,#base,children
|
|||
// so we are able to detect when the mouse leaves that frame area if there is no existing DOM element
|
|||
var $scrollContainer = $("<div id='scrollContainer'></div>"); |
|||
var $body = $('body'); |
|||
$scrollContainer.css({ |
|||
'position': 'fixed', |
|||
'width': $body.width(), |
|||
'height': $body.height() |
|||
}); |
|||
|
|||
// we want #base div to handle the event so that it bubbles up from the scrollContainer div which
|
|||
// handles the bounds of the frame in case there was no previously exisiting child to bubble up the
|
|||
// event or if the user has clicked on an existing child node to start the emulated touch scroll
|
|||
var $base = $('#base'); |
|||
$base.on('mouseleave.ax', function (e) { |
|||
var nS = $container.getNiceScroll(); |
|||
for (var i = 0; i < nS.length; ++i) |
|||
nS[i].ontouchend(e); |
|||
}); |
|||
// need to prepend so it is first child in DOM and doesn't block mouse events to other children which
|
|||
// would make them unable to scroll
|
|||
$base.prepend($scrollContainer); |
|||
} else { |
|||
$container.on('mouseleave.ax', function (e) { |
|||
var nS = $container.getNiceScroll(); |
|||
for (var i = 0; i < nS.length; ++i) |
|||
nS[i].ontouchend(e); |
|||
}); |
|||
} |
|||
} |
|||
|
|||
var _addNiceScroll = $ax.adaptive.addNiceScroll = function ($container, options, blockResetScroll) { |
|||
if (!blockResetScroll) { |
|||
$container.scrollLeft(0); |
|||
$container.scrollTop(0); |
|||
} |
|||
$container.niceScroll(options); |
|||
// RP-581 add handling to stop scroll on mouse leave if enable cursor-drag scrolling like touch devices in desktop computer
|
|||
if (options.emulatetouch) _addNiceScrollExitDetector($container); |
|||
//clean up nicescroll css so child scroll containers show scrollbars in IE
|
|||
if (IE) $container.css({ '-ms-overflow-y': '', '-ms-overflow-style': '' }); |
|||
if(IOS) $container.css({ 'overflow-y': ''}); |
|||
} |
|||
|
|||
//given the element, find the container that's using nice scroll (including the element itself)
|
|||
$ax.adaptive.getNiceScrollContainer = function(element) { |
|||
var parent = element; |
|||
while(parent) { |
|||
if($(parent).getNiceScroll().length > 0) return parent; |
|||
parent = parent.parentElement; |
|||
} |
|||
return undefined; |
|||
} |
|||
|
|||
|
|||
$ax.adaptive.updateMobileScrollOnBody = function () { |
|||
var niceScroll = $('html').getNiceScroll(); |
|||
if (niceScroll.length == 0) return; |
|||
niceScroll.resize(); |
|||
} |
|||
|
|||
var _setTrackpadHorizontalScroll = function (active) { |
|||
var preventScroll = function (e) { |
|||
if (Math.abs(e.wheelDeltaX) != 0) { |
|||
e.preventDefault(); |
|||
} |
|||
} |
|||
|
|||
if (!active) { |
|||
document.body.addEventListener("mousewheel", preventScroll, { passive: false }); |
|||
document.getElementById('html').addEventListener("mousewheel", preventScroll, { passive: false }); |
|||
} else { |
|||
document.body.removeEventListener("mousewheel", preventScroll, { passive: false }); |
|||
document.getElementById('html').removeEventListener("mousewheel", preventScroll, { passive: false }); |
|||
} |
|||
} |
|||
|
|||
var _setHorizontalScroll = function (active) { |
|||
var $body = $(document); |
|||
if (!active) { |
|||
$body.bind('scroll', function () { |
|||
if ($body.scrollLeft() !== 0) { |
|||
$body.scrollLeft(0); |
|||
} |
|||
}); |
|||
} else { |
|||
$body.unbind('scroll'); |
|||
} |
|||
} |
|||
|
|||
$ax.adaptive.setAdaptiveView = function(view) { |
|||
var viewIdForSitemapToUnderstand = view == 'auto' ? undefined : (view == 'default' ? '' : view); |
|||
|
|||
if(!_isAdaptiveInitialized()) { |
|||
_initialViewToLoad = viewIdForSitemapToUnderstand; |
|||
} else _handleLoadViewId(viewIdForSitemapToUnderstand); |
|||
}; |
|||
|
|||
$ax.adaptive.initialize = function() { |
|||
_views = $ax.pageData.adaptiveViews; |
|||
_idToView = {}; |
|||
|
|||
var useViews = $ax.document.configuration.useViews; |
|||
|
|||
if(_views && _views.length > 0) { |
|||
for(var i = 0; i < _views.length; i++) { |
|||
var view = _views[i]; |
|||
_idToView[view.id] = view; |
|||
if(useViews) _enabledViews[_enabledViews.length] = view; |
|||
} |
|||
|
|||
if(_autoIsHandledBySidebar && _initialViewSizeToLoad) _handleSetViewForSize(_initialViewSizeToLoad.width, _initialViewSizeToLoad.height); |
|||
else _handleLoadViewId(_initialViewToLoad); |
|||
} |
|||
|
|||
$axure.resize(function(e) { |
|||
_handleResize(); |
|||
$ax.postResize(e); //window resize fires after view changed
|
|||
}); |
|||
}; |
|||
|
|||
var _handleLoadViewId = function (loadViewId, forceSwitchTo) { |
|||
if(typeof loadViewId != 'undefined') { |
|||
_setAuto(false); |
|||
_switchView(loadViewId != 'default' ? loadViewId : '', forceSwitchTo); |
|||
} else { |
|||
_setAuto(true); |
|||
_handleResize(forceSwitchTo); |
|||
} |
|||
}; |
|||
|
|||
var _handleSetViewForSize = function (width, height) { |
|||
var toView = _getAdaptiveView(width, height); |
|||
var toViewId = toView && toView.id; |
|||
_switchView(toViewId, "auto"); |
|||
}; |
|||
|
|||
$ax.adaptive.getSketchKey = function() { |
|||
return $ax.pageData.sketchKeys[$ax.adaptive.currentViewId || '']; |
|||
} |
|||
}); |
@ -1,178 +0,0 @@ |
|||
// ******* Annotation MANAGER ******** //
|
|||
$axure.internal(function($ax) { |
|||
var NOTE_SIZE = 10; |
|||
|
|||
var _annotationManager = $ax.annotation = {}; |
|||
|
|||
var _updateLinkLocations = $ax.annotation.updateLinkLocations = function(elementId) { |
|||
var textId = $ax.GetTextPanelId(elementId); |
|||
if(!textId) return; |
|||
|
|||
var rotation = $ax.getObjectFromElementId(elementId).style.rotation; |
|||
//we have to do this because webkit reports the post-transform position but when you set positions it's pre-transform
|
|||
if(WEBKIT && rotation) { |
|||
//we can dynamiclly rotate a widget now, show need to remember the transform rather than just remove it
|
|||
//here jquery.css will return 'none' if element is display none
|
|||
var oldShapeTransform = document.getElementById(elementId).style['-webkit-transform']; |
|||
var oldTextTransform = document.getElementById(textId).style['-webkit-transform']; |
|||
$('#' + elementId).css('-webkit-transform', 'scale(1)'); |
|||
$('#' + textId).css('-webkit-transform', 'scale(1)'); |
|||
} |
|||
|
|||
$('#' + textId).find('div[id$="_ann"]').each(function(index, value) { |
|||
var elementId = value.id.replace('_ann', ''); |
|||
var $link = $('#' + elementId); |
|||
var annPos = $link.position(); |
|||
annPos.left += $link.width(); |
|||
//var annPos = $(value).position();
|
|||
var left = annPos.left;// - NOTE_SIZE;
|
|||
var top = annPos.top - 5; |
|||
|
|||
$(value).css('left', left).css('top', top); |
|||
}); |
|||
|
|||
//undo the transform reset
|
|||
if(WEBKIT && rotation) { |
|||
$('#' + elementId).css('-webkit-transform', oldShapeTransform || ''); |
|||
$('#' + textId).css('-webkit-transform', oldTextTransform || ''); |
|||
} |
|||
}; |
|||
|
|||
var _toggleAnnotationDialog = function (elementId, event) { |
|||
let win = $(window); |
|||
let scrollY = win.scrollTop(); |
|||
let scrollX = win.scrollLeft(); |
|||
|
|||
let x = event.pageX - scrollX; |
|||
let y = event.pageY - scrollY; |
|||
|
|||
let frameElement = window.frameElement; |
|||
let parent = window.parent; |
|||
//ann dialog is relative to mainFrame, exclude the mainFrame location so the notes shows up correctly in device mode
|
|||
while(frameElement && frameElement.name !== 'mainFrame') { |
|||
let rect = frameElement.getBoundingClientRect(); |
|||
x += rect.x; |
|||
y += rect.y; |
|||
|
|||
if(!parent) break; |
|||
|
|||
frameElement = parent.frameElement; |
|||
parent = parent.parent; |
|||
} |
|||
|
|||
let messageData = { id: elementId, x: x, y: y } |
|||
if (!$axure.utils.isInPlayer()) messageData.page = $ax.pageData.notesData; |
|||
$ax.messageCenter.postMessage('toggleAnnDialog', messageData); |
|||
} |
|||
|
|||
$ax.annotation.initialize = function () { |
|||
_createFootnotes($ax('*'), true); |
|||
} |
|||
|
|||
var _createFootnotes = $ax.annotation.createFootnotes = function(query, create) { |
|||
if(!$ax.document.configuration.showAnnotations) return; |
|||
|
|||
var widgetNotes = $ax.pageData.notesData.widgetNotes; |
|||
if (widgetNotes) { |
|||
var ownerToFns = $ax.pageData.notesData.ownerToFns; |
|||
if(!$.isEmptyObject(ownerToFns)) { |
|||
query.each(function(dObj, elementId) { |
|||
var fns = ownerToFns[dObj.id]; |
|||
if (fns !== undefined) { |
|||
var elementIdQuery = $('#' + elementId); |
|||
if (dObj.type == 'hyperlink') { |
|||
var parentId = $ax.GetParentIdFromLink(elementId); |
|||
if (create) { |
|||
elementIdQuery.after("<div id='" + elementId + "_ann' class='annnote'>​</div>"); |
|||
appendFns($('#' + elementId + "_ann"), fns); |
|||
} |
|||
_updateLinkLocations(parentId); |
|||
} else { |
|||
if (create) { |
|||
elementIdQuery.after("<div id='" + elementId + "_ann' class='annnote'>​</div>"); |
|||
appendFns($('#' + elementId + "_ann"), fns); |
|||
} |
|||
_adjustIconLocation(elementId, dObj); |
|||
} |
|||
|
|||
if (create) { |
|||
$('#' + elementId + "_ann").click(function (e) { |
|||
_toggleAnnotationDialog(dObj.id, e); |
|||
return false; |
|||
}); |
|||
|
|||
var isVisible = true; |
|||
var isMaster = $ax.public.fn.IsReferenceDiagramObject(dObj.type); |
|||
if (isMaster) isVisible = dObj.visible; |
|||
else isVisible = $ax.visibility.IsIdVisible(elementId); |
|||
if (!isVisible) { |
|||
var ann = document.getElementById(elementId + "_ann"); |
|||
if (ann) $ax.visibility.SetVisible(ann, false); |
|||
} |
|||
} |
|||
} |
|||
}); |
|||
} |
|||
} |
|||
|
|||
function appendFns($parent, fns) { |
|||
for (var index = 0; index < fns.length; index++) { |
|||
$parent.append("<div class='annnotelabel' >" + fns[index] + "</div>"); |
|||
} |
|||
} |
|||
}; |
|||
|
|||
$ax.annotation.updateAllFootnotes = function () { |
|||
_createFootnotes($ax('*'), false); |
|||
} |
|||
|
|||
$ax.annotation.jQueryAnn = function(query) { |
|||
var elementIds = []; |
|||
query.each(function(diagramObject, elementId) { |
|||
if(diagramObject.annotation) elementIds[elementIds.length] = elementId; |
|||
}); |
|||
var elementIdSelectors = jQuery.map(elementIds, function(elementId) { return '#' + elementId + '_ann'; }); |
|||
var jQuerySelectorText = (elementIdSelectors.length > 0) ? elementIdSelectors.join(', ') : ''; |
|||
return $(jQuerySelectorText); |
|||
}; |
|||
|
|||
$(window.document).ready(function() { |
|||
//$ax.annotation.InitializeAnnotations($ax(function(dObj) { return dObj.annotation; }));
|
|||
|
|||
$ax.messageCenter.addMessageListener(function(message, data) { |
|||
//If the annotations are being hidden via the Sitemap toggle button, hide any open dialogs
|
|||
if(message == 'annotationToggle') { |
|||
if (data == true) { |
|||
$('div.annnote').show(); |
|||
} else { |
|||
$('div.annnote').hide(); |
|||
} |
|||
} |
|||
}); |
|||
}); |
|||
|
|||
//adjust annotation location to a element's top right corner
|
|||
var _adjustIconLocation = $ax.annotation.adjustIconLocation = function(id, dObj) { |
|||
var ann = document.getElementById(id + "_ann"); |
|||
if(ann) { |
|||
var corners = $ax.public.fn.getCornersFromComponent(id); |
|||
var width = $(ann).width(); |
|||
var newTopRight = $ax.public.fn.vectorPlus(corners.relativeTopRight, corners.centerPoint); |
|||
//note size is 14x8, this is how rp calculated it as well
|
|||
ann.style.left = (newTopRight.x - width) + "px"; |
|||
|
|||
var elementType = dObj ? dObj.type : $ax.getTypeFromElementId(id); |
|||
var yOffset = $ax.public.fn.IsTableCell(elementType) ? 0 : -8; |
|||
ann.style.top = (newTopRight.y + yOffset) + "px"; |
|||
} |
|||
|
|||
var ref = document.getElementById(id + "_ref"); |
|||
if(ref) { |
|||
if(!corners) corners = $ax.public.fn.getCornersFromComponent(id); |
|||
var newBottomRight = $ax.public.fn.vectorPlus(corners.relativeBottomRight, corners.centerPoint); |
|||
|
|||
ref.style.left = (newBottomRight.x - 8) + 'px'; |
|||
ref.style.top = (newBottomRight.y - 10) + 'px'; |
|||
} |
|||
} |
|||
}); |
@ -1,407 +0,0 @@ |
|||
$axure = function(query) { |
|||
return $axure.query(query); |
|||
}; |
|||
|
|||
// ******* AxQuery and Page metadata ******** //
|
|||
(function() { |
|||
var $ax = function() { |
|||
var returnVal = $axure.apply(this, arguments); |
|||
var axFn = $ax.fn; |
|||
for (var key in axFn) { |
|||
returnVal[key] = axFn[key]; |
|||
} |
|||
|
|||
return returnVal; |
|||
}; |
|||
|
|||
$ax.public = $axure; |
|||
$ax.fn = {}; |
|||
|
|||
$axure.internal = function(initFunction) { |
|||
//Attach messagecenter to $ax object so that it can be used in viewer.js, etc in internal scope
|
|||
if(!$ax.messageCenter) $ax.messageCenter = $axure.messageCenter; |
|||
|
|||
return initFunction($ax); |
|||
}; |
|||
|
|||
var _lastFiredResize = 0; |
|||
var _resizeFunctions = []; |
|||
var _lastTimeout; |
|||
var _fireResize = function() { |
|||
if (_lastTimeout) window.clearTimeout(_lastTimeout); |
|||
_lastTimeout = undefined; |
|||
_lastFiredResize = new Date().getTime(); |
|||
for(var i = 0; i < _resizeFunctions.length; i++) _resizeFunctions[i](); |
|||
}; |
|||
|
|||
$axure.resize = function(fn) { |
|||
if(fn) _resizeFunctions[_resizeFunctions.length] = fn; |
|||
else $(window).resize(); |
|||
}; |
|||
|
|||
$(window).resize(function() { |
|||
var THRESHOLD = 50; |
|||
_updateWindowInfo(); |
|||
var now = new Date().getTime(); |
|||
if(now - _lastFiredResize > THRESHOLD) { |
|||
_fireResize(); |
|||
} else if(!_lastTimeout) { |
|||
_lastTimeout = window.setTimeout(_fireResize, THRESHOLD); |
|||
} |
|||
}); |
|||
|
|||
$(window).scroll(function () { |
|||
_updateWindowInfo(); |
|||
}); |
|||
|
|||
var _windowInfo; |
|||
var _updateWindowInfo = $axure.updateWindowInfo = function () { |
|||
var win = {}; |
|||
var jWin = $(window); |
|||
var scrollWin = $('#ios-safari-html').length > 0 ? $('#ios-safari-html') : jWin; |
|||
win.width = jWin.width(); |
|||
win.height = jWin.height(); |
|||
win.scrollx = scrollWin.scrollLeft(); |
|||
win.scrolly = scrollWin.scrollTop(); |
|||
_windowInfo = win; |
|||
}; |
|||
$ax.getWindowInfo = function () { |
|||
if(!_windowInfo) _updateWindowInfo(); |
|||
return _windowInfo; |
|||
}; |
|||
|
|||
|
|||
window.$obj = function(id) { |
|||
return $ax.getObjectFromElementId(id); |
|||
}; |
|||
|
|||
window.$id = function(obj) { |
|||
return obj.scriptIds[0]; |
|||
}; |
|||
|
|||
window.$jobj = function(id) { |
|||
return $(document.getElementById(id)); |
|||
}; |
|||
|
|||
window.$jobjAll = function(id) { |
|||
return $addAll($jobj(id), id); |
|||
}; |
|||
|
|||
window.$addAll = function(jobj, id) { |
|||
return jobj.add($jobj(id + '_ann')).add($jobj(id + '_ref')); |
|||
}; |
|||
|
|||
$ax.INPUT = function(id) { return id + "_input"; }; |
|||
$ax.IsImageFocusable = function (type) { return $ax.public.fn.IsImageBox(type) || $ax.public.fn.IsVector(type) || $ax.public.fn.IsTreeNodeObject(type) || $ax.public.fn.IsTableCell(type); }; |
|||
$ax.IsTreeNodeObject = function (type) { return $ax.public.fn.IsTreeNodeObject(type); }; |
|||
$ax.IsSelectionButton = function (type) { return $ax.public.fn.IsCheckBox(type) || $ax.public.fn.IsRadioButton(type); }; |
|||
|
|||
var _fn = {}; |
|||
$axure.fn = _fn; |
|||
$axure.fn.jQuery = function() { |
|||
var elements = this.getElements(); |
|||
return $(elements); |
|||
}; |
|||
$axure.fn.$ = $axure.fn.jQuery; |
|||
|
|||
var _query = function(query, queryArg) { |
|||
var returnVal = {}; |
|||
var _axQueryObject = returnVal.query = { }; |
|||
_axQueryObject.filterFunctions = []; |
|||
|
|||
if (query == '*') { |
|||
_axQueryObject.filterFunctions[0] = function() { return true; }; |
|||
} else if (typeof(query) === 'function') { |
|||
_axQueryObject.filterFunctions[0] = query; |
|||
} else { |
|||
var firstString = $.trim(query.toString()); |
|||
if (firstString.charAt(0) == '@') { |
|||
_axQueryObject.filterFunctions[0] = function(diagramObject) { |
|||
return diagramObject.label == firstString.substring(1); |
|||
}; |
|||
} else if (firstString.charAt(0) == '#') { |
|||
_axQueryObject.elementId = firstString.substring(1); |
|||
} else { |
|||
if (firstString == 'label') { |
|||
_axQueryObject.filterFunctions[0] = function(diagramObject) { |
|||
return queryArg instanceof Array && queryArg.indexOf(diagramObject.label) > 0 || |
|||
queryArg instanceof RegExp && queryArg.test(diagramObject.label) || |
|||
diagramObject.label == queryArg; |
|||
}; |
|||
} else if(firstString == 'elementId') { |
|||
_axQueryObject.filterFunctions[0] = function(diagramObject, elementId) { |
|||
return queryArg instanceof Array && queryArg.indexOf(elementId) > 0 || |
|||
elementId == queryArg; |
|||
}; |
|||
} |
|||
} |
|||
} |
|||
|
|||
var axureFn = $axure.fn; |
|||
for (var key in axureFn) { |
|||
returnVal[key] = axureFn[key]; |
|||
} |
|||
return returnVal; |
|||
}; |
|||
$axure.query = _query; |
|||
|
|||
var _getFilterFnFromQuery = function(query) { |
|||
var filter = function(diagramObject, elementId) { |
|||
// Non diagram objects are allowed to be queryed, such as text inputs.
|
|||
if (diagramObject && !$ax.public.fn.IsReferenceDiagramObject(diagramObject.type) && !document.getElementById(elementId)) return false; |
|||
var retVal = true; |
|||
for(var i = 0; i < query.filterFunctions.length && retVal; i++) { |
|||
retVal = query.filterFunctions[i](diagramObject, elementId); |
|||
} |
|||
return retVal; |
|||
}; |
|||
return filter; |
|||
}; |
|||
|
|||
$ax.public.fn.filter = function(query, queryArg) { |
|||
var returnVal = _query(query, queryArg); |
|||
|
|||
if(this.query.elementId) returnVal.query.elementId = this.query.elementId; |
|||
|
|||
//If there is already a function, offset by 1 when copying other functions over.
|
|||
var offset = returnVal.query.filterFunctions[0] ? 1 : 0; |
|||
|
|||
//Copy all functions over to new array.
|
|||
for(var i = 0; i < this.query.filterFunctions.length; i++) returnVal.query.filterFunctions[i+offset] = this.query.filterFunctions[i]; |
|||
|
|||
//Functions are in reverse order now
|
|||
returnVal.query.filterFunctions.reverse(); |
|||
|
|||
return returnVal; |
|||
}; |
|||
|
|||
$ax.public.fn.each = function(fn) { |
|||
var filter = _getFilterFnFromQuery(this.query); |
|||
var elementIds = this.query.elementId ? [this.query.elementId] : $ax.getAllElementIds(); |
|||
for (var i = 0; i < elementIds.length; i++) { |
|||
var elementId = elementIds[i]; |
|||
var diagramObject = $ax.getObjectFromElementId(elementId); |
|||
if (filter(diagramObject, elementId)) { |
|||
fn.apply(diagramObject, [diagramObject, elementId]); |
|||
} |
|||
} |
|||
}; |
|||
|
|||
$ax.public.fn.getElements = function() { |
|||
var elements = []; |
|||
this.each(function(dObj, elementId) { |
|||
var elementById = document.getElementById(elementId); |
|||
if(elementById) elements[elements.length] = elementById; |
|||
}); |
|||
return elements; |
|||
}; |
|||
|
|||
$ax.public.fn.getElementIds = function() { |
|||
var elementIds = []; |
|||
this.each(function(dObj, elementId) { elementIds[elementIds.length] = elementId; }); |
|||
return elementIds; |
|||
}; |
|||
|
|||
// Deep means to keep getting parents parent until at the root parent. Parent is then an array instead of an id.
|
|||
// Filter options: layer, rdo, repeater, item, dynamicPanel, state
|
|||
$ax.public.fn.getParents = function (deep, filter) { |
|||
if(filter == '*') filter = ['layer', 'rdo', 'repeater', 'item', 'dynamicPanel', 'state']; |
|||
var elementIds = this.getElementIds(); |
|||
var parentIds = []; |
|||
|
|||
var getParent = function(elementId) { |
|||
var containerIndex = elementId.indexOf('_container'); |
|||
if(containerIndex !== -1) elementId = elementId.substring(0, containerIndex); |
|||
if(elementId.indexOf('_text') !== -1) elementId = $ax.GetShapeIdFromText(elementId); |
|||
|
|||
// Check repeater item before layer, because repeater item detects it's parent layer, but wants to go directly to it's repeater first.
|
|||
// if repeater item, then just return repeater
|
|||
var scriptId = $ax.repeater.getScriptIdFromElementId(elementId); |
|||
var itemNum = $ax.repeater.getItemIdFromElementId(elementId); |
|||
var parentRepeater = $ax.getParentRepeaterFromScriptId(scriptId); |
|||
|
|||
// scriptId is item or repeater itself
|
|||
if (parentRepeater == scriptId) { |
|||
// If you are repeater item, return your repeater
|
|||
if (itemNum) return filter.indexOf('repeater') != -1 ? scriptId : getParent(scriptId); |
|||
// Otherwise you are actually at repeater, clean parentRepeater, or else you loop
|
|||
parentRepeater = undefined; |
|||
} |
|||
|
|||
// Layer only references it if it is a direct layer to it
|
|||
var parent = $ax.getLayerParentFromElementId(elementId); |
|||
// If layer is allowed we found parent, otherwise ignore and keep climbing
|
|||
if (parent) return filter.indexOf('layer') != -1 ? parent : getParent(parent); |
|||
|
|||
// if state, then just return panel
|
|||
if(scriptId.indexOf('_state') != -1) { |
|||
var panelId = $ax.repeater.createElementId(scriptId.split('_')[0], itemNum); |
|||
// If dynamic panel is allowed we found parent, otherwise ignore and keep climbing
|
|||
return filter.indexOf('dynamicPanel') != -1 ? panelId : getParent(panelId); |
|||
} |
|||
|
|||
var parentType = ''; |
|||
if(parentRepeater) { |
|||
parentType = 'item'; |
|||
parent = $ax.repeater.createElementId(parentRepeater, itemNum); |
|||
} |
|||
|
|||
var masterPath = $ax.getPathFromScriptId($ax.repeater.getScriptIdFromElementId(elementId)); |
|||
masterPath.pop(); |
|||
if(masterPath.length > 0) { |
|||
var masterId = $ax.getElementIdFromPath(masterPath, { itemNum: itemNum }, true); |
|||
if(!masterId) return undefined; |
|||
var masterRepeater = $ax.getParentRepeaterFromElementId($ax.repeater.getScriptIdFromElementId(masterId)); |
|||
if(!parentRepeater || masterRepeater) { |
|||
parentType = 'rdo'; |
|||
parent = masterId; |
|||
} |
|||
} |
|||
|
|||
var obj = $obj(elementId); |
|||
var parentDynamicPanel = obj.parentDynamicPanel; |
|||
if(parentDynamicPanel) { |
|||
// Make sure the parent if not parentRepeater, or dynamic panel is also in that repeater
|
|||
// If there is a parent master, the dynamic panel must be in it, otherwise parentDynamicPanel would be undefined.
|
|||
var panelPath = masterPath; |
|||
panelPath[panelPath.length] = parentDynamicPanel; |
|||
panelId = $ax.getElementIdFromPath(panelPath, { itemNum: itemNum }, true); |
|||
if(!panelId) return undefined; |
|||
var panelRepeater = $ax.getParentRepeaterFromElementId(panelId); |
|||
if(!parentRepeater || panelRepeater) { |
|||
parentType = 'state'; |
|||
parent = panelId + '_state' + obj.panelIndex; |
|||
} |
|||
} |
|||
|
|||
// If at top or parent type is desired, then return parent, otherwise keep climbing
|
|||
return !parent || filter.indexOf(parentType) != -1 ? parent : getParent(parent); |
|||
}; |
|||
|
|||
for (var i = 0; i < elementIds.length; i++) { |
|||
var elementId = elementIds[i]; |
|||
if ((elementId || elementId === 0) && elementId !== "undefined") { |
|||
var parent = getParent(elementId); |
|||
if (deep) { |
|||
var parents = []; |
|||
while (parent) { |
|||
parents[parents.length] = parent; |
|||
// If id is not a valid object, you are either repeater item or dynamic panel state
|
|||
//if(!$obj(parent)) parent = $ax.visibility.getWidgetFromContainer($jobj(parent).parent().attr('id'));
|
|||
|
|||
parent = getParent(parent); |
|||
} |
|||
parent = parents; |
|||
} |
|||
parentIds[parentIds.length] = parent; |
|||
} |
|||
} |
|||
return parentIds; |
|||
}; |
|||
|
|||
// Get the path to the child, where non leaf nodes can be masters, layers, dynamic panels, and repeaters.
|
|||
$ax.public.fn.getChildren = function(deep, ignoreUnplaced) { // ignoreUnplaced should probably be the default, but when that is done a full audit of usages should be done
|
|||
var elementIds = this.getElementIds(); |
|||
var children = []; |
|||
|
|||
var getChildren = function (elementId) { |
|||
var obj = $obj(elementId); |
|||
//if(!obj) return undefined;
|
|||
|
|||
var isRepeater = obj && obj.type == $ax.constants.REPEATER_TYPE; |
|||
if (isRepeater && $ax.repeater.getScriptIdFromElementId(elementId) != elementId) { |
|||
//prevent repeater items from being marked as isRepeater
|
|||
//TODO: evaluate changing the naming convention to be more like panel states which don't seem to have this problem
|
|||
obj = undefined; |
|||
isRepeater = false; |
|||
} |
|||
var isDynamicPanel = obj && obj.type == $ax.constants.DYNAMIC_PANEL_TYPE; |
|||
//var isLayer = obj.type == $ax.constants.LAYER_TYPE;
|
|||
//var isMaster = obj.type == $ax.constants.MASTER_TYPE || obj.type == $ax.constants.REFERENCE_DIAGRAM_OBJECT_TYPE;
|
|||
|
|||
var isMenu = obj && obj.type == $ax.constants.MENU_OBJECT_TYPE; |
|||
var isTreeNode = obj && obj.type == $ax.constants.TREE_NODE_OBJECT_TYPE; |
|||
//var isTable = obj.type == $ax.constants.TABLE_TYPE;
|
|||
//var isCompoundVector = obj.type == $ax.constants.VECTOR_SHAPE_TYPE && obj.generateCompound;
|
|||
|
|||
//if (isRepeater || isDynamicPanel || isLayer || isMaster || isMenu || isTreeNode || isTable) {// || isCompoundVector) {
|
|||
// Find parent that children should be pulled from. Default is just the elementId query (used by table and master)
|
|||
var parent = $jobj(elementId); |
|||
if(isRepeater) { |
|||
parent = $(); |
|||
var itemIds = $ax.getItemIdsForRepeater(elementId); |
|||
for(var itemIndex = 0; itemIndex < itemIds.length; itemIndex++) parent = parent.add($jobj($ax.repeater.createElementId(elementId, itemIds[itemIndex]))); |
|||
} else if(isDynamicPanel) { |
|||
// Really only need to do active state probably...
|
|||
parent = $jobj(elementId).children(); |
|||
// Get through all containers
|
|||
while ($(parent[0]).attr('id').indexOf('container') != -1) parent = parent.children(); |
|||
// Now at states, but want states content
|
|||
parent = parent.children(); |
|||
} else if(isTreeNode) parent = $jobj($ax.repeater.applySuffixToElementId(elementId, '_children')); |
|||
|
|||
// Menu doesn't want all children, only tables and menus, so it must be handled specially
|
|||
var children = isMenu ? parent.children('.ax_table').add(parent.children('.ax_menu')) : parent.children(); |
|||
children = $ax.visibility.getRealChildren(_fixForBasicLinks(children)); |
|||
|
|||
// For tree nodes you want the the button shape contained by the elementQuery too
|
|||
if(isTreeNode) { |
|||
var treeNodeChildren = $jobj(elementId).children(); |
|||
for(var treeNodeIndex = 0; treeNodeIndex < treeNodeChildren.length; treeNodeIndex++) { |
|||
var treeNodeChild = $(treeNodeChildren[treeNodeIndex]); |
|||
var childObj = $obj(treeNodeChild.attr('id')); |
|||
if (childObj && $ax.public.fn.IsVector(childObj.type)) children = children.add(treeNodeChild); |
|||
} |
|||
} |
|||
|
|||
|
|||
var childrenIds = []; |
|||
for(var childIndex = 0; childIndex < children.length; childIndex++) { |
|||
var childObj = $(children[childIndex]); |
|||
var id = childObj.attr('id'); |
|||
if(typeof(id) == 'undefined' && childObj.is('a')) id = $(childObj.children()[0]).attr('id'); |
|||
// Ignore annotations and any other children that are not elements
|
|||
if (id.split('_').length > 1) continue; |
|||
// Ignore Unplaced
|
|||
if(ignoreUnplaced && $ax.visibility.isScriptIdLimbo($ax.repeater.getScriptIdFromElementId(id))) continue; |
|||
childrenIds.push(id); |
|||
} |
|||
|
|||
if(deep) { |
|||
var childObjs = []; |
|||
for(var i = 0; i < childrenIds.length; i++) { |
|||
var childId = childrenIds[i]; |
|||
childObjs[i] = { id: childId, children: getChildren(childId) }; |
|||
} |
|||
childrenIds = childObjs; |
|||
} |
|||
|
|||
return childrenIds; |
|||
//}
|
|||
|
|||
//return undefined;
|
|||
}; |
|||
|
|||
for(var i = 0; i < elementIds.length; i++) { |
|||
var elementId = elementIds[i]; |
|||
//if the state is passed in, look for children in the content element
|
|||
if (elementId.indexOf('_state') > -1 && elementId.indexOf('_content') < 0) elementId = elementId + '_content'; |
|||
children[children.length] = { id: elementId, children: getChildren(elementId)}; |
|||
} |
|||
return children; |
|||
}; |
|||
|
|||
var _fixForBasicLinks = function(query) { |
|||
var hasBasicLinks = query.filter('.basiclink').length > 0; |
|||
if(!hasBasicLinks) return query; |
|||
|
|||
var retval = $(); |
|||
for(var i = 0; i < query.length; i++) { |
|||
var child = $(query[i]); |
|||
if(child.hasClass('basiclink')) retval = retval.add(child.children()); |
|||
else retval = retval.add(child); |
|||
} |
|||
return retval; |
|||
}; |
|||
|
|||
})(); |
@ -1,900 +0,0 @@ |
|||
$axure.internal(function($ax) { |
|||
var _pageData; |
|||
|
|||
|
|||
var _initializePageFragment = function(pageFragment, objIdToObject) { |
|||
var objectArrayHelper = function(objects, parent) { |
|||
for(var i = 0; i < objects.length; i++) { |
|||
diagramObjectHelper(objects[i], parent); |
|||
} |
|||
}; |
|||
|
|||
var diagramObjectHelper = function(diagramObject, parent) { |
|||
$ax.initializeObject('diagramObject', diagramObject); |
|||
objIdToObject[pageFragment.packageId + '~' + diagramObject.id] = diagramObject; |
|||
diagramObject.parent = parent; |
|||
diagramObject.owner = pageFragment; |
|||
diagramObject.scriptIds = []; |
|||
if(diagramObject.diagrams) { //dynamic panel
|
|||
for(var i = 0; i < diagramObject.diagrams.length; i++) { |
|||
var diagram = diagramObject.diagrams[i]; |
|||
objectArrayHelper(diagram.objects, diagram); |
|||
} |
|||
} else if($ax.public.fn.IsLayer(diagramObject.type)) { |
|||
var layerObjs = diagramObject.objs; |
|||
objectArrayHelper(layerObjs, parent); |
|||
} |
|||
if(diagramObject.objects) objectArrayHelper(diagramObject.objects, diagramObject); |
|||
}; |
|||
objectArrayHelper(pageFragment.diagram.objects, pageFragment.diagram); |
|||
}; |
|||
|
|||
var _initalizeStylesheet = function(stylesheet) { |
|||
var stylesById = {}; |
|||
var customStyles = stylesheet.customStyles; |
|||
for(var key in customStyles) { |
|||
var style = customStyles[key]; |
|||
stylesById[style.id] = style; |
|||
} |
|||
var duplicateStyles = stylesheet.duplicateStyles; |
|||
for(var duplicateKey in duplicateStyles) { |
|||
stylesById[duplicateKey] = stylesById[duplicateStyles[duplicateKey]]; |
|||
} |
|||
|
|||
stylesheet.stylesById = stylesById; |
|||
}; |
|||
|
|||
|
|||
var _initializeDocumentData = function() { |
|||
_initalizeStylesheet($ax.document.stylesheet); |
|||
}; |
|||
|
|||
|
|||
var _initializePageData; |
|||
// ******* Dictionaries ******** //
|
|||
(function() { |
|||
var scriptIdToParentLayer = {}; |
|||
var elementIdToObject = {}; |
|||
var scriptIdToObject = {}; |
|||
var scriptIdToRepeaterId = {}; |
|||
var repeaterIdToScriptIds = {}; |
|||
var repeaterIdToItemIds = {}; |
|||
var scriptIdToPath = {}; |
|||
var _scriptIds = []; |
|||
var elementIdToText = {}; |
|||
var radioGroupToSelectedElementId = {}; |
|||
_initializePageData = function() { |
|||
if(!_pageData || !_pageData.page || !_pageData.page.diagram) return; |
|||
|
|||
var objIdToObject = {}; |
|||
_initializePageFragment(_pageData.page, objIdToObject); |
|||
for(var masterId in _pageData.masters) { |
|||
var master = _pageData.masters[masterId]; |
|||
_initializePageFragment(master, objIdToObject); |
|||
} |
|||
|
|||
var _pathsToScriptIds = []; |
|||
_pathToScriptIdHelper(_pageData.objectPaths, [], _pathsToScriptIds, scriptIdToPath); |
|||
|
|||
for(var i = 0; i < _pathsToScriptIds.length; i++) { |
|||
var path = _pathsToScriptIds[i].idPath; |
|||
var scriptId = _pathsToScriptIds[i].scriptId; |
|||
|
|||
var packageId = _pageData.page.packageId; |
|||
if(path.length > 1) { |
|||
for(var j = 0; j < path.length - 1; j++) { |
|||
var rdoId = path[j]; |
|||
var rdo = objIdToObject[packageId + '~' + rdoId]; |
|||
packageId = rdo.masterId; |
|||
} |
|||
} |
|||
var diagramObject = objIdToObject[packageId + '~' + path[path.length - 1]]; |
|||
diagramObject.scriptIds[diagramObject.scriptIds.length] = scriptId; |
|||
|
|||
scriptIdToObject[scriptId] = diagramObject; |
|||
_scriptIds[_scriptIds.length] = scriptId; |
|||
} |
|||
|
|||
// Now map scriptIds to repeaters and layers
|
|||
var mapScriptIdToRepeaterId = function(scriptId, repeaterId) { |
|||
scriptIdToRepeaterId[scriptId] = repeaterId; |
|||
var scriptIds = repeaterIdToScriptIds[repeaterId]; |
|||
if(scriptIds) scriptIds[scriptIds.length] = scriptId; |
|||
else repeaterIdToScriptIds[repeaterId] = [scriptId]; |
|||
}; |
|||
var mapScriptIdToLayerId = function(obj, layerId, path) { |
|||
var pathCopy = $ax.deepCopy(path); |
|||
pathCopy[path.length] = obj.id; |
|||
var scriptId = $ax.getScriptIdFromPath(pathCopy); |
|||
scriptIdToParentLayer[scriptId] = layerId; |
|||
} |
|||
var mapIdsToRepeaterAndLayer = function(path, objs, repeaterId) { |
|||
var pathCopy = $ax.deepCopy(path); |
|||
|
|||
for(var i = 0; i < objs.length; i++) { |
|||
var obj = objs[i]; |
|||
pathCopy[path.length] = obj.id; |
|||
var scriptId = $ax.getScriptIdFromPath(pathCopy); |
|||
// Rdo have no element on page and are not mapped to the repeater
|
|||
if(repeaterId) mapScriptIdToRepeaterId(scriptId, repeaterId); |
|||
|
|||
if($ax.public.fn.IsDynamicPanel(obj.type)) { |
|||
for(var j = 0; j < obj.diagrams.length; j++) mapIdsToRepeaterAndLayer(path, obj.diagrams[j].objects, repeaterId); |
|||
} else if($ax.public.fn.IsReferenceDiagramObject(obj.type)) { |
|||
mapIdsToRepeaterAndLayer(pathCopy, $ax.pageData.masters[obj.masterId].diagram.objects, repeaterId); |
|||
} else if($ax.public.fn.IsRepeater(obj.type)) { |
|||
mapScriptIdToRepeaterId(scriptId, scriptId); |
|||
mapIdsToRepeaterAndLayer(path, obj.objects, scriptId); |
|||
} else if($ax.public.fn.IsLayer(obj.type)) { |
|||
var layerObjs = obj.objs; |
|||
for(var j = 0; j < layerObjs.length; j++) { |
|||
mapScriptIdToLayerId(layerObjs[j], scriptId, path); |
|||
} |
|||
mapIdsToRepeaterAndLayer(path, layerObjs, repeaterId); |
|||
} else if(obj.objects && obj.objects.length) { |
|||
if(repeaterId) { |
|||
for(var j = 0; j < obj.objects.length; j++) { |
|||
mapIdsToRepeaterAndLayer(path, obj.objects, repeaterId); |
|||
} |
|||
} |
|||
} |
|||
} |
|||
}; |
|||
mapIdsToRepeaterAndLayer([], $ax.pageData.page.diagram.objects); |
|||
}; |
|||
|
|||
|
|||
$ax.getPathFromScriptId = function(scriptId) { |
|||
var reversedPath = []; |
|||
var path = scriptIdToPath[scriptId]; |
|||
while(path && path.uniqueId) { |
|||
reversedPath[reversedPath.length] = path.uniqueId; |
|||
path = path.parent; |
|||
} |
|||
return reversedPath.reverse(); |
|||
}; |
|||
|
|||
var _getScriptIdFromFullPath = function(path) { |
|||
var current = $ax.pageData.objectPaths; |
|||
for(var i = 0; i < path.length; i++) { |
|||
current = current[path[i]]; |
|||
if(!current) return current; |
|||
} |
|||
return current && current.scriptId; |
|||
}; |
|||
|
|||
|
|||
var _getScriptIdFromPath = function(path, relativeTo, includeLimbo) { |
|||
var relativePath = []; |
|||
var includeMasterInPath = false; |
|||
if(relativeTo) { |
|||
var relativeToScriptId; |
|||
if(relativeTo.srcElement) { //this is eventInfo
|
|||
relativeToScriptId = $ax.repeater.getScriptIdFromElementId(relativeTo.srcElement); |
|||
includeMasterInPath = relativeTo.isMasterEvent; |
|||
} else if(typeof relativeTo === 'string') { //this is an element id
|
|||
relativeToScriptId = relativeTo; |
|||
} |
|||
|
|||
if(relativeToScriptId) { |
|||
relativePath = $ax.getPathFromScriptId(relativeToScriptId); |
|||
if(!includeMasterInPath) relativePath = relativePath.slice(0, relativePath.length - 1); |
|||
} else if(relativeTo instanceof Array) { //this is a path
|
|||
relativePath = relativeTo; |
|||
} |
|||
} |
|||
var fullPath = relativePath.concat(path); |
|||
var scriptId = _getScriptIdFromFullPath(fullPath); |
|||
return (includeLimbo || !$ax.visibility.isScriptIdLimbo(scriptId)) && scriptId; |
|||
}; |
|||
$ax.getScriptIdFromPath = _getScriptIdFromPath; |
|||
|
|||
var _getElementIdsFromPath = function(path, eventInfo) { |
|||
var scriptId = _getScriptIdFromPath(path, eventInfo); |
|||
if(!scriptId) return []; |
|||
// Don't need placed check hear. If unplaced, scriptId will be undefined and exit out before here.
|
|||
return $ax.getElementIdsFromEventAndScriptId(eventInfo, scriptId); |
|||
}; |
|||
$ax.getElementIdsFromPath = _getElementIdsFromPath; |
|||
|
|||
var _getElementIdFromPath = function(path, params, includeLimbo) { |
|||
var scriptId = _getScriptIdFromPath(path, params.relativeTo, includeLimbo); |
|||
if(!scriptId) return scriptId; |
|||
|
|||
var itemNum = params.itemNum; |
|||
if(params.relativeTo && typeof params.relativeTo === 'string') { |
|||
if($jobj(params.relativeTo)) itemNum = $ax.repeater.getItemIdFromElementId(params.relativeTo); |
|||
} |
|||
return $ax.repeater.createElementId(scriptId, itemNum); |
|||
}; |
|||
$ax.getElementIdFromPath = _getElementIdFromPath; |
|||
|
|||
var _getElementsIdFromEventAndScriptId = function(eventInfo, scriptId) { |
|||
var itemId = eventInfo && $ax.repeater.getItemIdFromElementId(eventInfo.srcElement); |
|||
var target = false; |
|||
// Try to get itemId from target if you can't get it from source.
|
|||
if(!itemId) { |
|||
itemId = eventInfo && eventInfo.targetElement && $ax.repeater.getItemIdFromElementId(eventInfo.targetElement); |
|||
if(itemId) target = true; |
|||
} |
|||
|
|||
var parentRepeater = $ax.getParentRepeaterFromScriptId(scriptId); |
|||
if(parentRepeater && scriptId != parentRepeater) { |
|||
if(itemId && (!eventInfo || parentRepeater == $ax.getParentRepeaterFromScriptId($ax.repeater.getScriptIdFromElementId(target ? eventInfo.targetElement : eventInfo.srcElement)))) { |
|||
return [$ax.repeater.createElementId(scriptId, itemId)]; |
|||
} |
|||
var elementIds = []; |
|||
var itemIds = $ax.getItemIdsForRepeater(parentRepeater); |
|||
if(!itemIds) return []; |
|||
|
|||
for(var i = 0; i < itemIds.length; i++) elementIds[i] = $ax.repeater.createElementId(scriptId, itemIds[i]); |
|||
return elementIds; |
|||
} |
|||
return [scriptId]; |
|||
}; |
|||
$ax.getElementIdsFromEventAndScriptId = _getElementsIdFromEventAndScriptId; |
|||
|
|||
var _getSrcElementIdFromEvent = function(event) { |
|||
var currentQuery = $(event.srcElement || event.target); |
|||
while(currentQuery && currentQuery.length && (!$obj(currentQuery.attr('id')) || $jobj(currentQuery.attr('id')).hasClass('text'))) { |
|||
currentQuery = currentQuery.parent(); |
|||
}; |
|||
return currentQuery.attr('id'); |
|||
}; |
|||
$ax.getSrcElementIdFromEvent = _getSrcElementIdFromEvent; |
|||
|
|||
var _getEventInfoFromEvent = function(event, skipShowDescriptions, elementId) { |
|||
var eventInfo = {}; |
|||
eventInfo.srcElement = elementId; |
|||
eventInfo.now = new Date(); |
|||
|
|||
if(event != null) { |
|||
//elementId can be empty string, so can't simple use "or" assignment here.
|
|||
eventInfo.srcElement = elementId || elementId == '' ? elementId : _getSrcElementIdFromEvent(event); |
|||
eventInfo.which = event.which; |
|||
|
|||
// When getting locations in mobile, need to extract the touch object to get the mouse location attributes
|
|||
var mouseEvent = (event.originalEvent && event.originalEvent.changedTouches && event.originalEvent.changedTouches[0]) || event.originalEvent; |
|||
if(mouseEvent && !mouseEvent.type) mouseEvent.type = event.type; |
|||
|
|||
if(skipShowDescriptions) eventInfo.skipShowDescriptions = true; |
|||
|
|||
// Always update mouse location if possible
|
|||
$ax.event.updateMouseLocation(mouseEvent); |
|||
} |
|||
|
|||
// Always set event info about cursor
|
|||
var _cursor = eventInfo.cursor = {}; |
|||
_cursor.x = $ax.mouseLocation.x; |
|||
_cursor.y = $ax.mouseLocation.y; |
|||
|
|||
var body = $('body'); |
|||
if(body.css('position') == 'relative') { |
|||
_cursor.x -= ($ax.getNumFromPx(body.css('left')) + Math.max(0, ($(window).width() - body.width()) / 2)); |
|||
} |
|||
|
|||
eventInfo.pageX = _cursor.x + 'px'; |
|||
eventInfo.pageY = _cursor.y + 'px'; |
|||
|
|||
// Do Keyboard Info
|
|||
eventInfo.keyInfo = $ax.event.keyState(); |
|||
|
|||
eventInfo.window = $ax.getWindowInfo(); |
|||
|
|||
eventInfo.thiswidget = _getWidgetInfo(eventInfo.srcElement); |
|||
eventInfo.item = _getItemInfo(eventInfo.srcElement); |
|||
eventInfo.dragInfo = $ax.drag.GetWidgetDragInfo(); |
|||
|
|||
return eventInfo; |
|||
}; |
|||
$ax.getEventInfoFromEvent = _getEventInfoFromEvent; |
|||
|
|||
$ax.getBasicEventInfo = function() { |
|||
var eventInfo = {}; |
|||
eventInfo.now = new Date(); |
|||
eventInfo.window = $ax.getWindowInfo(); |
|||
eventInfo.cursor = { x: 0, y: 0}; |
|||
return eventInfo; |
|||
|
|||
}; |
|||
|
|||
//var _getWindowInfo = function() {
|
|||
// var win = {};
|
|||
// win.width = $(window).width();
|
|||
// win.height = $(window).height();
|
|||
// win.scrollx = $(window).scrollLeft();
|
|||
// win.scrolly = $(window).scrollTop();
|
|||
// return win;
|
|||
//};
|
|||
//$ax.getWindowInfo = _getWindowInfo;
|
|||
|
|||
var repeaterInfoCache = []; |
|||
$ax.cacheRepeaterInfo = function(repeaterId, repeaterInfo) { |
|||
repeaterInfoCache[repeaterId] = repeaterInfo; |
|||
} |
|||
$ax.removeCachedRepeaterInfo = function(repeaterId) { |
|||
repeaterInfoCache[repeaterId] = undefined; |
|||
} |
|||
|
|||
var _getItemInfo = function(elementId) { |
|||
if(!elementId) return { valid: false }; |
|||
|
|||
elementId = _getParentElement(elementId); |
|||
|
|||
var index = $ax.repeater.getItemIdFromElementId(elementId); |
|||
if(!index) return { valid: false }; |
|||
|
|||
var item = { valid: true }; |
|||
|
|||
var scriptId = $ax.repeater.getScriptIdFromElementId(elementId); |
|||
var repeaterId = $ax.getParentRepeaterFromScriptId(scriptId); |
|||
item.repeater = repeaterInfoCache[repeaterId] ? repeaterInfoCache[repeaterId] : _getWidgetInfo(repeaterId); |
|||
$ax.repeater.setDisplayProps(item, repeaterId, index); |
|||
item.ismarked = $ax.repeater.isEditItem(repeaterId, index); |
|||
item.isvisible = Boolean($jobj(elementId).length); |
|||
|
|||
return item; |
|||
}; |
|||
$ax.getItemInfo = _getItemInfo; |
|||
|
|||
var _getWidgetInfo = function(elementId) { |
|||
if(!elementId) return { valid: false }; |
|||
|
|||
elementId = _getParentElement(elementId); |
|||
|
|||
//var elementAxQuery = $ax('#' + elementId);
|
|||
var elementQuery = $jobj(elementId); |
|||
var obj = $obj(elementId); |
|||
var widget = { valid: true, isWidget: true, obj: obj, elementQuery: elementQuery, isLayer: $ax.public.fn.IsLayer(obj.type) }; |
|||
widget.elementId = elementId; |
|||
widget.name = widget.label = (elementQuery.data('label') ? elementQuery.data('label') : ''); |
|||
//widget.text = $ax('#' + elementId).text();
|
|||
widget.opacity = Number(elementQuery.css('opacity')) * 100; |
|||
//widget.rotation = $ax.move.getRotationDegree(widget.elementId);
|
|||
var scriptId = $ax.repeater.getScriptIdFromElementId(elementId); |
|||
var repeaterId = $ax.getParentRepeaterFromScriptId(scriptId); |
|||
if(repeaterId) widget.repeater = $ax.public.fn.IsRepeater(obj.type) ? widget : _getWidgetInfo(repeaterId); |
|||
|
|||
// Right now only dynamic panel can scroll
|
|||
if($ax.public.fn.IsDynamicPanel(obj.type)) { |
|||
var stateId = $ax.visibility.GetPanelState(elementId); |
|||
//can be empty when refreshing repeater and applying filter
|
|||
if(stateId) { |
|||
var stateQuery = $('#' + stateId); |
|||
widget.scrollx = stateQuery.scrollLeft(); |
|||
widget.scrolly = stateQuery.scrollTop(); |
|||
//widget.stateQuery = stateQuery;
|
|||
} |
|||
} else { |
|||
widget.scrollx = 0; |
|||
widget.scrolly = 0; |
|||
} |
|||
|
|||
// repeater only props
|
|||
if($ax.public.fn.IsRepeater(obj.type)) { |
|||
widget.visibleitemcount = repeaterIdToItemIds[scriptId] ? repeaterIdToItemIds[scriptId].length : $ax.repeater.getVisibleDataCount(scriptId); |
|||
widget.itemcount = $ax.repeater.getFilteredDataCount(scriptId); |
|||
widget.datacount = $ax.repeater.getDataCount(scriptId); |
|||
widget.pagecount = $ax.repeater.getPageCount(scriptId); |
|||
widget.pageindex = $ax.repeater.getPageIndex(scriptId); |
|||
} |
|||
|
|||
// Get widget info funcs
|
|||
//widget.elementAxQuery = function () {
|
|||
// return this.elementAxQueryProp || (this.elementAxQueryProp = $ax('#' + this.elementId));
|
|||
//}
|
|||
|
|||
//widget.isFitToContent = function () {
|
|||
// if (this.isFitToContentProp === undefined) {
|
|||
// if (!this.stateQuery) this.isFitToContentProp = false;
|
|||
// else this.isFitToContentProp = $ax.dynamicPanelManager.isIdFitToContent(this.elementId);
|
|||
// }
|
|||
// return this.isFitToContentProp;
|
|||
//}
|
|||
|
|||
widget.x = function () { return this.getProp('x'); } |
|||
widget.y = function () { return this.getProp('y'); } |
|||
widget.pagex = function () { return this.getProp('pagex'); } |
|||
widget.pagey = function () { return this.getProp('pagey'); } |
|||
widget.width = function () { return this.getProp('width'); } |
|||
widget.height = function () { return this.getProp('height'); } |
|||
widget.left = function () { return this.x(); } |
|||
widget.top = function () { return this.y(); } |
|||
widget.right = function () { return this.x() + this.width(); } |
|||
widget.bottom = function () { return this.y() + this.height(); } |
|||
widget.rotation = function () { return this.getProp('rotation'); } |
|||
widget.text = function () { return this.getProp('text'); } |
|||
|
|||
widget.getProp = function (prop) { |
|||
var propName = prop + 'Prop'; |
|||
if (typeof (this[propName]) != 'undefined') return this[propName]; |
|||
return this[propName] = this.cacheProp(prop); |
|||
}; |
|||
|
|||
widget.cacheProp = function (prop) { |
|||
|
|||
if(prop == 'x' || prop == 'y' || prop == 'width' || prop == 'height') { |
|||
var boundingRect = $ax('#' + this.elementId).offsetBoundingRect(true); |
|||
this.xProp = boundingRect.left; |
|||
this.yProp = boundingRect.top; |
|||
this.widthProp = boundingRect.width; |
|||
this.heightProp = boundingRect.height; |
|||
} |
|||
|
|||
if(prop == 'pagex' || prop == 'pagey') { |
|||
var viewportLocation = $ax('#' + this.elementId).viewportLocation(); |
|||
this.pagexProp = viewportLocation.left; |
|||
this.pageyProp = viewportLocation.top; |
|||
} |
|||
|
|||
if(prop == 'rotation') { |
|||
this.rotationProp = $ax.move.getRotationDegree(this.elementId); |
|||
} |
|||
|
|||
if (prop == 'text') { |
|||
this.textProp = $ax('#' + this.elementId).text(); |
|||
} |
|||
|
|||
return this[prop + 'Prop']; |
|||
|
|||
//// I'm keeping the returned undefineds the same as before, but really I could probably return undefined right away if elementQuery is empty
|
|||
//if (this.isLayer) {
|
|||
// if (prop == 'pagex' || prop == 'pagey') {
|
|||
// if (this.elementQuery.length > 0) {
|
|||
// if (prop == 'pagex') return this.elementAxQuery().left();
|
|||
// else return this.elementAxQuery().top();
|
|||
// }
|
|||
// return undefined; // Otherwise, it is undefined as there is no element
|
|||
// }
|
|||
// var boundingRect = $ax.public.fn.getWidgetBoundingRect(this.elementId);
|
|||
// this.xProp = boundingRect.left;
|
|||
// this.yProp = boundingRect.top;
|
|||
// this.widthProp = boundingRect.width;
|
|||
// this.heightProp = boundingRect.height;
|
|||
// return this[prop + 'Prop'];
|
|||
//}
|
|||
|
|||
//if (this.elementQuery.length <= 0) return prop == 'x' || prop == 'y' ? 0 : undefined;
|
|||
|
|||
//switch (prop) {
|
|||
// case 'x': return this.elementAxQuery().locRelativeIgnoreLayer(false);
|
|||
// case 'y': return this.elementAxQuery().locRelativeIgnoreLayer(true);
|
|||
// case 'pagex': return this.elementAxQuery().left();
|
|||
// case 'pagey': return this.elementAxQuery().top();
|
|||
//}
|
|||
|
|||
//var val = this.elementAxQuery()[prop]();
|
|||
//if (this.isFitToContent()) val = this.stateQuery[prop]();
|
|||
|
|||
//return val;
|
|||
}; |
|||
|
|||
//widget.leftfixed = function() { this.getFixed('left'); }
|
|||
//widget.topfixed = function() { this.getFixed('top'); }
|
|||
//widget.rightfixed = function() { this.getFixed('right'); }
|
|||
//widget.bottomfixed = function() { this.getFixed('bottom'); }
|
|||
|
|||
//widget.isFixed = function() {
|
|||
// if(this.isFixedProp === undefined) this.isFixedProp = this.elementQuery.css('position') == 'fixed)';
|
|||
// return this.isFixedProp;
|
|||
//}
|
|||
|
|||
//widget.getFixed = function (prop) {
|
|||
// var fixed = prop + 'fixedProp';
|
|||
// if(!this.isFixed()) widget[fixed] = widget[prop]();
|
|||
// if(widget[fixed] === undefined) {
|
|||
|
|||
// if(prop == 'left' || prop == 'right') {
|
|||
// if(this.windowScrollX === undefined) this.windowScrollX = $(window).scrollLeft();
|
|||
// var windowScroll = this.windowScrollX;
|
|||
// } else {
|
|||
// if(this.windowScrollY === undefined) this.windowScrollY = $(window).scrollTop();
|
|||
// windowScroll = this.windowScrollY;
|
|||
// }
|
|||
// widget[fixed] = widget[prop]() - windowScroll;
|
|||
// }
|
|||
// return widget[fixed];
|
|||
//}
|
|||
|
|||
return widget; |
|||
}; |
|||
$ax.getWidgetInfo = _getWidgetInfo; |
|||
|
|||
$ax.GetTextPanelId = function (id, create) { |
|||
if(!$ax('#' + id).SupportsRichText()) return ''; |
|||
var buttonShape = $ax.GetButtonShape(id); |
|||
var panelDiv = buttonShape.find('.text')[0]; |
|||
if(!panelDiv) { |
|||
if(!create) return ""; |
|||
|
|||
var adaptiveId = $ax.adaptive.currentViewId; |
|||
var newId = id + "_text"; |
|||
//var newDiv = $('<div id="' + newId + '" class="text" style="visibility: inherit; position: absolute"></div>');
|
|||
var newDiv = $('<div id="' + newId + '" class="text' + (adaptiveId ? (' ' + adaptiveId) : '') + '" style="visibility: inherit; position: absolute"><p><span></span></p></div>'); |
|||
buttonShape.append(newDiv); |
|||
|
|||
$ax.style.setAdaptiveStyle(id, $ax.style.computeAllOverrides(id, undefined, $ax.style.generateState(id), adaptiveId)); |
|||
|
|||
panelDiv = newDiv[0]; |
|||
} |
|||
|
|||
return panelDiv.id; |
|||
} |
|||
|
|||
$ax.GetParentIdFromLink = function(id) { |
|||
return $ax.GetShapeIdFromText($jobj(id).parentsUntil('.text').parent().attr('id')); |
|||
}; |
|||
|
|||
$ax.GetButtonShapeId = function(id) { |
|||
var obj = $obj(id); |
|||
switch(obj.type) { |
|||
case $ax.constants.TREE_NODE_OBJECT_TYPE: |
|||
return obj.buttonShapeId ? $ax.getElementIdFromPath([obj.buttonShapeId], { relativeTo: id }) : ""; |
|||
case $ax.constants.LINK_TYPE: |
|||
return ""; |
|||
default: |
|||
return id; |
|||
} |
|||
}; |
|||
|
|||
$ax.GetButtonShape = function(id) { |
|||
return $jobj($ax.GetButtonShapeId(id)); |
|||
}; |
|||
|
|||
$ax.GetShapeIdFromText = function(id) { |
|||
if(!id) return undefined; // this is to prevent an infinite loop.
|
|||
|
|||
var current = document.getElementById(id); |
|||
if(!current) return undefined; |
|||
current = current.parentElement; |
|||
while(current && current.tagName != 'BODY') { |
|||
var currentId = current.id; |
|||
if(currentId && currentId != 'base') return $ax.visibility.getWidgetFromContainer(currentId); |
|||
current = current.parentElement; |
|||
} |
|||
|
|||
return undefined; |
|||
}; |
|||
|
|||
$ax.GetImageIdFromShape = function(id) { |
|||
var image = $ax.GetButtonShape(id).find('img[id$=img]'); |
|||
if(!image.length) image = $jobj(id).find('img[id$=image_sketch]'); |
|||
return image.attr('id'); |
|||
}; |
|||
|
|||
var _getParentElement = $ax.getParentElement = function(elementId) { |
|||
var obj = $obj(elementId); |
|||
while(obj.isContained) { |
|||
var path = $ax.getPathFromScriptId($ax.repeater.getScriptIdFromElementId(elementId)); |
|||
var itemId = $ax.repeater.getItemIdFromElementId(elementId); |
|||
path[path.length - 1] = obj.parent.id; |
|||
elementId = $ax.getElementIdFromPath(path, { itemNum: itemId }); |
|||
obj = $obj(elementId); |
|||
} |
|||
|
|||
return elementId; |
|||
}; |
|||
|
|||
$ax.addItemIdToRepeater = function(itemId, repeaterId) { |
|||
var itemIds = repeaterIdToItemIds[repeaterId]; |
|||
if(itemIds) itemIds[itemIds.length] = itemId; |
|||
else repeaterIdToItemIds[repeaterId] = [itemId]; |
|||
|
|||
var scriptIds = repeaterIdToScriptIds[repeaterId]; |
|||
for(var i = 0; i < scriptIds.length; i++) elementIdToObject[$ax.repeater.createElementId(scriptIds[i], itemId)] = $ax.getObjectFromScriptId(scriptIds[i]); |
|||
}; |
|||
|
|||
$ax.getAllElementIds = function() { |
|||
var elementIds = []; |
|||
for(var i = 0; i < _scriptIds.length; i++) { |
|||
var scriptId = _scriptIds[i]; |
|||
var repeaterId = scriptIdToRepeaterId[scriptId]; |
|||
if(repeaterId && repeaterId != scriptId) { |
|||
var itemIds = repeaterIdToItemIds[repeaterId] || []; |
|||
for(var j = 0; j < itemIds.length; j++) elementIds[elementIds.length] = $ax.repeater.createElementId(scriptId, itemIds[j]); |
|||
} else elementIds[elementIds.length] = scriptId; |
|||
} |
|||
return elementIds; |
|||
}; |
|||
|
|||
$ax.getAllScriptIds = function() { |
|||
return _scriptIds; |
|||
}; |
|||
|
|||
$ax.getObjectFromElementId = function(elementId) { |
|||
return $ax.getObjectFromScriptId($ax.repeater.getScriptIdFromElementId(elementId)); |
|||
}; |
|||
|
|||
$ax.getObjectFromScriptId = function(scriptId) { |
|||
return scriptIdToObject[scriptId]; |
|||
}; |
|||
|
|||
$ax.getParentRepeaterFromElementId = function(elementId) { |
|||
return $ax.getParentRepeaterFromScriptId($ax.repeater.getScriptIdFromElementId(elementId)); |
|||
}; |
|||
|
|||
$ax.getParentRepeaterFromElementIdExcludeSelf = function (elementId) { |
|||
var repeaterId = $ax.getParentRepeaterFromElementId(elementId); |
|||
return repeaterId != elementId ? repeaterId : undefined; |
|||
}; |
|||
|
|||
$ax.getParentRepeaterFromScriptId = function(scriptId) { |
|||
return scriptIdToRepeaterId[scriptId]; |
|||
}; |
|||
|
|||
var _getChildScriptIdsForRepeater = function(repeaterId) { |
|||
return repeaterIdToScriptIds[repeaterId]; |
|||
}; |
|||
|
|||
var _getItemIdsForRepeater = function(repeaterId) { |
|||
return repeaterIdToItemIds[repeaterId] || []; |
|||
}; |
|||
$ax.getItemIdsForRepeater = _getItemIdsForRepeater; |
|||
|
|||
var _clearItemIdsForRepeater = function(repeaterId) { |
|||
repeaterIdToItemIds[repeaterId] = []; |
|||
}; |
|||
$ax.clearItemsForRepeater = _clearItemIdsForRepeater; |
|||
|
|||
$ax.getChildElementIdsForRepeater = function(repeaterId) { |
|||
var scriptIds = _getChildScriptIdsForRepeater(repeaterId); |
|||
var itemIds = _getItemIdsForRepeater(repeaterId); |
|||
|
|||
var retVal = []; |
|||
if(!itemIds || !scriptIds) return retVal; |
|||
|
|||
for(var i = 0; i < scriptIds.length; i++) { |
|||
for(var j = 0; j < itemIds.length; j++) { |
|||
retVal[retVal.length] = $ax.repeater.createElementId(scriptIds[i], itemIds[j]); |
|||
} |
|||
} |
|||
return retVal; |
|||
}; |
|||
|
|||
$ax.getRdoParentFromElementId = function(elementId) { |
|||
var scriptId = $ax.repeater.getScriptIdFromElementId(elementId); |
|||
var rdoId = scriptIdToPath[scriptId].parent.scriptId; |
|||
if($ax.getParentRepeaterFromScriptId(rdoId)) rdoId = $ax.repeater.createElementId(rdoId, $ax.repeater.getItemIdFromElementId(elementId)); |
|||
return rdoId; |
|||
}; |
|||
|
|||
$ax.getLayerParentFromElementId = function (elementId) { |
|||
var itemId = $ax.repeater.getItemIdFromElementId(elementId); |
|||
var scriptId = scriptIdToParentLayer[$ax.repeater.getScriptIdFromElementId(elementId)]; |
|||
return $ax.getParentRepeaterFromElementId(scriptId) ? $ax.repeater.createElementId(scriptId, itemId) : scriptId; |
|||
} |
|||
|
|||
$ax.updateElementText = function(elementId, text) { |
|||
elementIdToText[elementId] = text; |
|||
}; |
|||
|
|||
$ax.hasElementTextChanged = function(elementId, text) { |
|||
return elementIdToText[elementId] != text; |
|||
}; |
|||
|
|||
$ax.updateRadioButtonSelected = function(group, elementId) { |
|||
var old = radioGroupToSelectedElementId[group]; |
|||
radioGroupToSelectedElementId[group] = elementId; |
|||
return old; |
|||
}; |
|||
|
|||
$ax.hasRadioButtonSelectedChanged = function(group, elementId) { |
|||
return radioGroupToSelectedElementId[group] != elementId; |
|||
}; |
|||
})(); |
|||
|
|||
//Recursively populates fullPathArray with:
|
|||
// [ { idPath, scriptId }, ... ]
|
|||
//for every scriptId in the object
|
|||
//also populates an object of scriptId -> path
|
|||
var _pathToScriptIdHelper = function(currentPath, currentChain, fullPathArray, scriptIdToPath) { |
|||
for(var key in currentPath) { |
|||
if(key != "scriptId") { |
|||
var nextPath = currentPath[key]; |
|||
_pathToScriptIdHelper(nextPath, currentChain.concat(key), fullPathArray, scriptIdToPath); |
|||
nextPath.parent = currentPath; |
|||
nextPath.uniqueId = key; |
|||
} else { |
|||
fullPathArray[fullPathArray.length] = { idPath: currentChain, scriptId: currentPath.scriptId }; |
|||
scriptIdToPath[currentPath.scriptId] = currentPath; |
|||
} |
|||
} |
|||
}; |
|||
|
|||
$ax.public.loadCurrentPage = $ax.loadCurrentPage = function(pageData) { |
|||
$ax.pageData = _pageData = pageData; |
|||
_initializePageData(); |
|||
}; |
|||
|
|||
$ax.public.loadDocument = $ax.loadDocument = function(document) { |
|||
$ax.document = document; |
|||
_initializeDocumentData(); |
|||
}; |
|||
|
|||
|
|||
/** |
|||
Navigates to a page |
|||
|
|||
|
|||
*/ |
|||
$ax.public.navigate = $ax.navigate = function(to) { //url, includeVariables, type) {
|
|||
var targetUrl; |
|||
if(typeof (to) === 'object') { |
|||
targetUrl = !to.includeVariables ? to.url : $ax.globalVariableProvider.getLinkUrl(to.url, to.useGlobalVarNameInUrl); |
|||
|
|||
if(to.target == "new") { |
|||
window.open(targetUrl, ""); |
|||
} else if(to.target == "popup") { |
|||
var features = _getPopupFeatures(to.popupOptions); |
|||
window.open(targetUrl, "", features); |
|||
} else { |
|||
var targetLocation = window.location; |
|||
if(to.target == "current") { |
|||
} else if(to.target == "parent") { |
|||
if(!top.opener) return; |
|||
targetLocation = top.opener.window.location; |
|||
} else if(to.target == "parentFrame") { |
|||
targetLocation = parent.location; |
|||
} else if(to.target == "frame") { |
|||
// targetLocation = to.frame.contentWindow.location;
|
|||
$(to.frame).attr('src', targetUrl || 'about:blank'); |
|||
return; |
|||
} |
|||
|
|||
if (!_needsReload(targetLocation, to.url)) { |
|||
targetLocation.href = targetUrl || 'about:blank'; |
|||
} else { |
|||
targetLocation.href = $axure.utils.getReloadPath() + "#" + encodeURI(targetUrl); |
|||
} |
|||
} |
|||
} else { |
|||
$ax.navigate({ |
|||
url: to, |
|||
target: "current", |
|||
includeVariables: arguments[1] |
|||
}); |
|||
} |
|||
}; |
|||
|
|||
var _needsReload = function(oldLocation, newBaseUrl) { |
|||
var reload = false; |
|||
try { |
|||
var oldUrl = oldLocation.href; |
|||
var oldBaseUrl = oldUrl.split("#")[0]; |
|||
var lastslash = oldBaseUrl.lastIndexOf("/"); |
|||
if(lastslash > 0) { |
|||
oldBaseUrl = oldBaseUrl.substring(lastslash + 1, oldBaseUrl.length); |
|||
if(oldBaseUrl == encodeURI(newBaseUrl)) { |
|||
reload = true; |
|||
} |
|||
} |
|||
} catch(e) { |
|||
} |
|||
return reload; |
|||
}; |
|||
|
|||
var _getPopupFeatures = function(options) { |
|||
var defaultOptions = { |
|||
toolbar: true, |
|||
scrollbars: true, |
|||
location: true, |
|||
status: true, |
|||
menubar: true, |
|||
directories: true, |
|||
resizable: true, |
|||
centerwindow: true, |
|||
left: -1, |
|||
top: -1, |
|||
height: -1, |
|||
width: -1 |
|||
}; |
|||
|
|||
var selectedOptions = $.extend({}, defaultOptions, options); |
|||
|
|||
var optionsList = []; |
|||
optionsList.push('toolbar=' + (selectedOptions.toolbar ? 'yes' : 'no')); |
|||
optionsList.push('scrollbars=' + (selectedOptions.scrollbars ? 'yes' : 'no')); |
|||
optionsList.push('location=' + (selectedOptions.location ? 'yes' : 'no')); |
|||
optionsList.push('status=' + (selectedOptions.status ? 'yes' : 'no')); |
|||
optionsList.push('menubar=' + (selectedOptions.menubar ? 'yes' : 'no')); |
|||
optionsList.push('directories=' + (selectedOptions.directories ? 'yes' : 'no')); |
|||
optionsList.push('resizable=' + (selectedOptions.resizable ? 'yes' : 'no')); |
|||
|
|||
if(selectedOptions.centerwindow == false) { |
|||
if(selectedOptions.left > -1) { |
|||
optionsList.push('left=' + selectedOptions.left); |
|||
} |
|||
|
|||
if(selectedOptions.top > -1) { |
|||
optionsList.push('top=' + selectedOptions.top); |
|||
} |
|||
} |
|||
|
|||
var height = 0; |
|||
var width = 0; |
|||
if(selectedOptions.height > 0) { |
|||
optionsList.push('height=' + selectedOptions.height); |
|||
height = selectedOptions.height; |
|||
} |
|||
|
|||
if(selectedOptions.width > 0) { |
|||
optionsList.push('width=' + selectedOptions.width); |
|||
width = selectedOptions.width; |
|||
} |
|||
|
|||
var features = optionsList.join(','); |
|||
if(selectedOptions.centerwindow) { |
|||
var winl = (window.screen.width - width) / 2; |
|||
var wint = (window.screen.height - height) / 2; |
|||
features = features + ',left=' + winl + ',top=' + wint; |
|||
} |
|||
|
|||
return features; |
|||
}; |
|||
|
|||
/** |
|||
Closes a window |
|||
|
|||
|
|||
*/ |
|||
$ax.public.closeWindow = $ax.closeWindow = function() { |
|||
parent.window.close(); |
|||
}; |
|||
|
|||
/** |
|||
Goes back |
|||
|
|||
|
|||
*/ |
|||
$ax.public.back = $ax.back = function() { |
|||
window.history.go(-1); |
|||
}; |
|||
|
|||
/** |
|||
Reloads the current page. |
|||
# includeVariables: true if it should re-include the variables when the page is reloaded |
|||
*/ |
|||
$ax.public.reload = $ax.reload = function(includeVariables) { |
|||
var targetUrl = (includeVariables === false) |
|||
? $axure.utils.getReloadPath() + "#" + encodeURI($ax.pageData.url) |
|||
: $axure.utils.getReloadPath() + "#" + encodeURI($ax.globalVariableProvider.getLinkUrl($ax.pageData.url)); |
|||
window.location.href = targetUrl; |
|||
}; |
|||
|
|||
/** |
|||
Sets a variable. |
|||
# name: The name of the global variable to set |
|||
# value: The value that should be set |
|||
*/ |
|||
$ax.public.setGlobalVariable = $ax.setGlobalVariable = function(name, value) { |
|||
if(!name || !value) { |
|||
return; |
|||
} |
|||
|
|||
$ax.globalVariableProvider.setVariableValue(name, value); |
|||
}; |
|||
|
|||
/** |
|||
Gets the value of a global variable |
|||
# name: The name of the global variable value to get |
|||
*/ |
|||
$ax.public.getGlobalVariable = $ax.getGlobalVariable = function(name) { |
|||
$ax.globalVariableProvider.getVariableValue(name); |
|||
}; |
|||
|
|||
$ax.getObjectFromElementIdDisregardHex = function (elementId) { |
|||
var elementIdInput = elementId.charAt(0) == '#' ? elementId.substring(1) : elementId; |
|||
return this.getObjectFromElementId(elementIdInput); |
|||
} |
|||
|
|||
|
|||
$ax.getTypeFromElementId = function(elementId) { |
|||
var obj = this.getObjectFromElementIdDisregardHex(elementId); |
|||
return obj && obj.type; |
|||
}; |
|||
|
|||
$ax.getNumFromPx = function(pxNum) { |
|||
return Number(pxNum.replace('px', '')); |
|||
} |
|||
|
|||
}); |
@ -1,278 +0,0 @@ |
|||
$axure.internal(function($ax) { |
|||
var widgetDragInfo = new Object(); |
|||
var _drag = {}; |
|||
$ax.drag = _drag; |
|||
|
|||
$ax.drag.GetWidgetDragInfo = function() { |
|||
return $.extend({}, widgetDragInfo); |
|||
}; |
|||
|
|||
$ax.drag.StartDragWidget = function(event, id) { |
|||
$ax.setjBrowserEvent(jQuery.Event(event)); |
|||
//we should only start drag on one target, otherwise the _dragWidget and _stopDragWidget events from multiple targets will be conflicted
|
|||
if(event.donotdrag || widgetDragInfo.started) return; |
|||
|
|||
var x, y; |
|||
var tg; |
|||
if(IE_10_AND_BELOW) { |
|||
x = window.event.clientX + window.document.documentElement.scrollLeft + window.document.body.scrollLeft; |
|||
y = window.event.clientY + window.document.documentElement.scrollTop + window.document.body.scrollTop; |
|||
tg = window.event.srcElement; |
|||
} else { |
|||
if(event.changedTouches) { |
|||
x = event.changedTouches[0].pageX; |
|||
y = event.changedTouches[0].pageY; |
|||
} else { |
|||
x = event.pageX; |
|||
y = event.pageY; |
|||
event.preventDefault(); |
|||
} |
|||
tg = event.target; |
|||
} |
|||
|
|||
widgetDragInfo.started = true; |
|||
widgetDragInfo.hasDragged= false; |
|||
widgetDragInfo.widgetId = id; |
|||
widgetDragInfo.cursorStartX = x; |
|||
widgetDragInfo.cursorStartY = y; |
|||
widgetDragInfo.lastX = x; |
|||
widgetDragInfo.lastY = y; |
|||
widgetDragInfo.currentX = x; |
|||
widgetDragInfo.currentY = y; |
|||
|
|||
widgetDragInfo.movedWidgets = new Object(); |
|||
widgetDragInfo.startTime = (new Date()).getTime(); |
|||
widgetDragInfo.targetWidget = tg; |
|||
|
|||
var movedownName = IE_10_AND_BELOW && $ax.features.supports.windowsMobile ? |
|||
$ax.features.eventNames.mouseDownName : $ax.features.eventNames.mouseMoveName; |
|||
$ax.event.addEvent(document, movedownName, _dragWidget, true); |
|||
$ax.event.addEvent(document, $ax.features.eventNames.mouseUpName, _stopDragWidget, true); |
|||
|
|||
//$ax.legacy.SuppressBubble(event);
|
|||
}; |
|||
|
|||
var _dragWidget = function(event) { |
|||
$ax.setjBrowserEvent(jQuery.Event(event)); |
|||
|
|||
var x, y; |
|||
if(IE_10_AND_BELOW) { |
|||
x = window.event.clientX + window.document.documentElement.scrollLeft + window.document.body.scrollLeft; |
|||
y = window.event.clientY + window.document.documentElement.scrollTop + window.document.body.scrollTop; |
|||
} else { |
|||
if(event.changedTouches) { |
|||
x = event.changedTouches[0].pageX; |
|||
y = event.changedTouches[0].pageY; |
|||
//allow scroll (defaults) if only swipe events have cases and delta x is less than 5px and not blocking scrolling
|
|||
var deltaX = x - widgetDragInfo.currentX; |
|||
var target = window.document.getElementById(widgetDragInfo.widgetId); |
|||
if($ax.event.hasSyntheticEvent(widgetDragInfo.widgetId, "onDrag") || $ax.event.hasSyntheticEvent(widgetDragInfo.widgetId, "onSwipeUp") || |
|||
$ax.event.hasSyntheticEvent(widgetDragInfo.widgetId, "onSwipeDown") || (deltaX * deltaX) > 25 |
|||
|| ($ax.document.configuration.preventScroll && $ax.legacy.GetScrollable(target) == window.document.body)) { |
|||
event.preventDefault(); |
|||
} |
|||
} else { |
|||
x = event.pageX; |
|||
y = event.pageY; |
|||
} |
|||
} |
|||
widgetDragInfo.xDelta = x - widgetDragInfo.currentX; |
|||
widgetDragInfo.yDelta = y - widgetDragInfo.currentY; |
|||
widgetDragInfo.lastX = widgetDragInfo.currentX; |
|||
widgetDragInfo.lastY = widgetDragInfo.currentY; |
|||
widgetDragInfo.currentX = x; |
|||
widgetDragInfo.currentY = y; |
|||
|
|||
widgetDragInfo.currentTime = (new Date()).getTime(); |
|||
|
|||
// $ax.legacy.SuppressBubble(event);
|
|||
|
|||
if(!widgetDragInfo.hasDragged) { |
|||
widgetDragInfo.hasDragged = true; |
|||
$ax.event.raiseSyntheticEvent(widgetDragInfo.widgetId, "onDragStart"); |
|||
|
|||
//only update to move cursor is we are moving objects
|
|||
if($ax.event.hasSyntheticEvent(widgetDragInfo.widgetId, "onDrag")) { |
|||
widgetDragInfo.cursorChanged = true; |
|||
widgetDragInfo.oldBodyCursor = window.document.body.style.cursor; |
|||
window.document.body.style.cursor = 'move'; |
|||
var widget = window.document.getElementById(widgetDragInfo.widgetId); |
|||
widgetDragInfo.oldCursor = widget.style.cursor; |
|||
widget.style.cursor = 'move'; |
|||
//need to do this in order to change the cursor under nice scroll
|
|||
var niceScrollContainer = $ax.adaptive.getNiceScrollContainer(widget); |
|||
if(niceScrollContainer) { |
|||
widgetDragInfo.oldNiceScrollContainerCursor = niceScrollContainer.style.cursor; |
|||
niceScrollContainer.style.cursor = 'move'; |
|||
} |
|||
} |
|||
} |
|||
|
|||
$ax.event.raiseSyntheticEvent(widgetDragInfo.widgetId, "onDrag"); |
|||
}; |
|||
|
|||
var _suppressClickAfterDrag = function(event) { |
|||
_removeSuppressEvents(); |
|||
|
|||
$ax.legacy.SuppressBubble(event); |
|||
}; |
|||
|
|||
var _removeSuppressEvents = function () { |
|||
if(IE_10_AND_BELOW) { |
|||
$ax.event.removeEvent(event.srcElement, 'click', _suppressClickAfterDrag, undefined, true); |
|||
$ax.event.removeEvent(widgetDragInfo.targetWidget, 'mousemove', _removeSuppressEvents, undefined, true); |
|||
} else { |
|||
$ax.event.removeEvent(document, "click", _suppressClickAfterDrag, true); |
|||
$ax.event.removeEvent(document, 'mousemove', _removeSuppressEvents, true); |
|||
} |
|||
}; |
|||
|
|||
var _stopDragWidget = function(event) { |
|||
$ax.setjBrowserEvent(jQuery.Event(event)); |
|||
|
|||
var tg; |
|||
|
|||
|
|||
var movedownName = IE_10_AND_BELOW && $ax.features.supports.windowsMobile ? |
|||
$ax.features.eventNames.mouseDownName : $ax.features.eventNames.mouseMoveName; |
|||
$ax.event.removeEvent(document, movedownName, _dragWidget, true); |
|||
$ax.event.removeEvent(document, $ax.features.eventNames.mouseUpName, _stopDragWidget, true); |
|||
|
|||
tg = IE_10_AND_BELOW ? window.event.srcElement : event.target; |
|||
|
|||
if(widgetDragInfo.hasDragged) { |
|||
widgetDragInfo.currentTime = (new Date()).getTime(); |
|||
$ax.event.raiseSyntheticEvent(widgetDragInfo.widgetId, "onDragDrop"); |
|||
|
|||
if($ax.globalVariableProvider.getVariableValue('totaldragx') < -30 && $ax.globalVariableProvider.getVariableValue('dragtime') < 1000) { |
|||
$ax.event.raiseSyntheticEvent(widgetDragInfo.widgetId, "onSwipeLeft"); |
|||
} |
|||
|
|||
if($ax.globalVariableProvider.getVariableValue('totaldragx') > 30 && $ax.globalVariableProvider.getVariableValue('dragtime') < 1000) { |
|||
$ax.event.raiseSyntheticEvent(widgetDragInfo.widgetId, "onSwipeRight"); |
|||
} |
|||
|
|||
var totalDragY = $ax.globalVariableProvider.getVariableValue('totaldragy'); |
|||
if(totalDragY < -30 && $ax.globalVariableProvider.getVariableValue('dragtime') < 1000) { |
|||
$ax.event.raiseSyntheticEvent(widgetDragInfo.widgetId, "onSwipeUp"); |
|||
} |
|||
|
|||
if(totalDragY > 30 && $ax.globalVariableProvider.getVariableValue('dragtime') < 1000) { |
|||
$ax.event.raiseSyntheticEvent(widgetDragInfo.widgetId, "onSwipeDown"); |
|||
} |
|||
|
|||
if(widgetDragInfo.cursorChanged) { |
|||
window.document.body.style.cursor = widgetDragInfo.oldBodyCursor; |
|||
var widget = window.document.getElementById(widgetDragInfo.widgetId); |
|||
// It may be null if OnDragDrop filtered out the widget
|
|||
if(widget != null) widget.style.cursor = widgetDragInfo.oldCursor; |
|||
//we don't seems need to reset nicescroll cursor on container, nicescroll seems updates its cursor
|
|||
// if(widgetDragInfo.oldNiceScrollContainerCursor != undefined) {
|
|||
// var niceScrollContainer = $ax.adaptive.getNiceScrollContainer(widget);
|
|||
// if(niceScrollContainer) niceScrollContainer.style.cursor = widgetDragInfo.oldNiceScrollContainerCursor;
|
|||
// widgetDragInfo.oldNiceScrollContainerCursor = undefined;
|
|||
// }
|
|||
widgetDragInfo.cursorChanged = undefined; |
|||
} |
|||
|
|||
if(widgetDragInfo.targetWidget == tg && !event.changedTouches) { |
|||
// suppress the click after the drag on desktop browsers
|
|||
if(IE_10_AND_BELOW && widgetDragInfo.targetWidget) { |
|||
$ax.event.addEvent(widgetDragInfo.targetWidget, 'click', _suppressClickAfterDrag, true, true); |
|||
$ax.event.addEvent(widgetDragInfo.targetWidget, "onmousemove", _removeSuppressEvents, true, true); |
|||
} else { |
|||
$ax.event.addEvent(document, "click", _suppressClickAfterDrag, true); |
|||
$ax.event.addEvent(document, "mousemove", _removeSuppressEvents, true); |
|||
|
|||
} |
|||
} |
|||
} |
|||
|
|||
widgetDragInfo.hasDragged = false; |
|||
widgetDragInfo.movedWidgets = new Object(); |
|||
widgetDragInfo.started = false; |
|||
|
|||
return false; |
|||
}; |
|||
|
|||
$ax.drag.GetDragX = function() { |
|||
if(widgetDragInfo.hasDragged) return widgetDragInfo.xDelta; |
|||
return 0; |
|||
}; |
|||
|
|||
$ax.drag.GetDragY = function() { |
|||
if(widgetDragInfo.hasDragged) return widgetDragInfo.yDelta; |
|||
return 0; |
|||
}; |
|||
|
|||
$ax.drag.GetTotalDragX = function() { |
|||
if(widgetDragInfo.hasDragged) return widgetDragInfo.currentX - widgetDragInfo.cursorStartX; |
|||
return 0; |
|||
}; |
|||
|
|||
$ax.drag.GetTotalDragY = function() { |
|||
if(widgetDragInfo.hasDragged) return widgetDragInfo.currentY - widgetDragInfo.cursorStartY; |
|||
return 0; |
|||
}; |
|||
|
|||
$ax.drag.GetDragTime = function() { |
|||
if(widgetDragInfo.hasDragged) return widgetDragInfo.currentTime - widgetDragInfo.startTime; |
|||
return 600000; |
|||
}; |
|||
|
|||
$ax.drag.LogMovedWidgetForDrag = function (id, dragInfo) { |
|||
dragInfo = dragInfo || widgetDragInfo; |
|||
if(dragInfo.hasDragged) { |
|||
var containerIndex = id.indexOf('_container'); |
|||
if(containerIndex != -1) id = id.substring(0, containerIndex); |
|||
|
|||
// If state or other non-widget id, this should not be dragged, and should exit out to avoid exceptions.
|
|||
if(!$obj(id)) return; |
|||
|
|||
var query = $ax('#' + id); |
|||
//var x = query.left();
|
|||
//var y = query.top();
|
|||
var viewportLocation = query.viewportLocation(); |
|||
var x = viewportLocation.left; |
|||
var y = viewportLocation.top; |
|||
|
|||
var movedWidgets = dragInfo.movedWidgets; |
|||
if(!movedWidgets[id]) { |
|||
movedWidgets[id] = new Location(x, y); |
|||
} |
|||
} |
|||
}; |
|||
|
|||
var Location = function(x, y) { |
|||
this.x = x; |
|||
this.y = y; |
|||
}; |
|||
$ax.drag.location = Location; |
|||
|
|||
var Rectangle = $ax.drag.Rectangle = function(x, y, width, height) { |
|||
this.x = x; |
|||
this.y = y; |
|||
this.width = width; |
|||
this.height = height; |
|||
this.right = x + width; |
|||
this.bottom = y + height; |
|||
}; |
|||
|
|||
Rectangle.prototype.IntersectsWith = function(rect) { |
|||
if(this.Invalid()) return false; |
|||
if(rect.length) { |
|||
for(var i = 0; i < rect.length; i++) if(!rect[i].Invalid && this.IntersectsWith(rect[i])) return true; |
|||
return false; |
|||
} |
|||
if(rect.Invalid()) return false; |
|||
return this.x < rect.right && this.right > rect.x && this.y < rect.bottom && this.bottom > rect.y; |
|||
}; |
|||
|
|||
Rectangle.prototype.Invalid = function() { |
|||
return this.x == -1 && this.y == -1 && this.width == -1 && this.height == -1; |
|||
}; |
|||
|
|||
Rectangle.prototype.Move = function(x, y) { |
|||
return new Rectangle(x, y, this.width, this.height); |
|||
}; |
|||
}); |
@ -1,579 +0,0 @@ |
|||
// ******* Expr MANAGER ******** //
|
|||
$axure.internal(function($ax) { |
|||
var _expr = $ax.expr = {}; |
|||
var _binOpHandlers = { |
|||
'&&': function(left, right) { return _binOpOverride(left, right, function(left) { return $ax.getBool(left) && $ax.getBool(right()); }); }, |
|||
'||': function(left, right) { return _binOpOverride(left, right, function(left) { return $ax.getBool(left) || $ax.getBool(right()); }); }, |
|||
'==': function(left, right) { return isEqual(left, right, true); }, |
|||
'!=': function(left, right) { return !isEqual(left, right, true); }, |
|||
'>': function(left, right) { return _binOpNum(left, right, function(left, right) { return left > right; }); }, |
|||
'<': function(left, right) { return _binOpNum(left, right, function(left, right) { return left < right; }); }, |
|||
'>=': function(left, right) { return _binOpNum(left, right, function(left, right) { return left >= right; }); }, |
|||
'<=': function(left, right) { return _binOpNum(left, right, function(left, right) { return left <= right; }); } |
|||
}; |
|||
|
|||
var checkOps = function(left, right) { |
|||
return left == undefined || right == undefined; |
|||
}; |
|||
|
|||
var isEqual = function (left, right, isFunction) { |
|||
if (isFunction) { |
|||
//if left and right is function, then get the value
|
|||
//otherwise left and right should be already the value we want
|
|||
left = left(); |
|||
right = right(); |
|||
} |
|||
|
|||
if(checkOps(left, right)) return false; |
|||
|
|||
if(left instanceof Date && right instanceof Date) { |
|||
if(left.getMilliseconds() != right.getMilliseconds()) return false; |
|||
if(left.getSeconds() != right.getSeconds()) return false; |
|||
if(left.getMinutes() != right.getMinutes()) return false; |
|||
if(left.getHours() != right.getHours()) return false; |
|||
if(left.getDate() != right.getDate()) return false; |
|||
if(left.getMonth() != right.getMonth()) return false; |
|||
if(left.getYear() != right.getYear()) return false; |
|||
return true; |
|||
} |
|||
|
|||
if(left instanceof Object && right instanceof Object) { |
|||
var prop; |
|||
// Go through all of lefts properties and compare them to rights.
|
|||
for(prop in left) { |
|||
if(!left.hasOwnProperty(prop)) continue; |
|||
// If left has a property that the right doesn't they are not equal.
|
|||
if(!right.hasOwnProperty(prop)) return false; |
|||
// If any of their properties are not equal, they are not equal.
|
|||
if(!isEqual(left[prop], right[prop], false)) return false; |
|||
} |
|||
|
|||
for(prop in right) { |
|||
// final check to make sure right doesn't have some extra properties that make them not equal.
|
|||
if(left.hasOwnProperty(prop) != right.hasOwnProperty(prop)) return false; |
|||
} |
|||
|
|||
return true; |
|||
} |
|||
return $ax.getBool(left) == $ax.getBool(right); |
|||
}; |
|||
|
|||
var _binOpOverride = function(left, right, func) { |
|||
left = left(); |
|||
if(left == undefined) return false; |
|||
var res = func(left, right); |
|||
return res == undefined ? false : res; |
|||
}; |
|||
|
|||
var _binOpNum = function(left, right, func) { |
|||
var left = left(); |
|||
var right = right(); |
|||
if(checkOps(left, right)) return false; |
|||
|
|||
return func(left, Number(right)); |
|||
}; |
|||
|
|||
var _exprHandlers = {}; |
|||
_exprHandlers.array = function(expr, eventInfo) { |
|||
var returnVal = []; |
|||
for(var i = 0; i < expr.items.length; i++) { |
|||
returnVal[returnVal.length] = _evaluateExpr(expr.items[i], eventInfo); |
|||
} |
|||
return returnVal; |
|||
}; |
|||
|
|||
_exprHandlers.binaryOp = function(expr, eventInfo) { |
|||
var left = function() { return expr.leftExpr && _evaluateExpr(expr.leftExpr, eventInfo); }; |
|||
var right = function() { return expr.rightExpr && _evaluateExpr(expr.rightExpr, eventInfo); }; |
|||
|
|||
if(left == undefined || right == undefined) return false; |
|||
return _binOpHandlers[expr.op](left, right); |
|||
}; |
|||
|
|||
_exprHandlers.block = function(expr, eventInfo) { |
|||
var subExprs = expr.subExprs; |
|||
for(var i = 0; i < subExprs.length; i++) { |
|||
_evaluateExpr(subExprs[i], eventInfo); //ignore the result
|
|||
} |
|||
}; |
|||
|
|||
_exprHandlers.booleanLiteral = function(expr) { |
|||
return expr.value; |
|||
}; |
|||
|
|||
_exprHandlers.nullLiteral = function() { return null; }; |
|||
|
|||
_exprHandlers.pathLiteral = function(expr, eventInfo) { |
|||
if(expr.isThis) return [eventInfo.srcElement]; |
|||
if(expr.isFocused && window.lastFocusedControl) { |
|||
$ax('#' + window.lastFocusedControl).focus(); |
|||
return [window.lastFocusedControl]; |
|||
} |
|||
if(expr.isTarget) return [eventInfo.targetElement]; |
|||
|
|||
return $ax.getElementIdsFromPath(expr.value, eventInfo); |
|||
}; |
|||
|
|||
_exprHandlers.panelDiagramLiteral = function(expr, eventInfo) { |
|||
var elementIds = $ax.getElementIdsFromPath(expr.panelPath, eventInfo); |
|||
var elementIdsWithSuffix = []; |
|||
var suffix = '_state' + expr.panelIndex; |
|||
for(var i = 0; i < elementIds.length; i++) { |
|||
elementIdsWithSuffix[i] = $ax.repeater.applySuffixToElementId(elementIds[i], suffix); |
|||
} |
|||
return String($jobj(elementIdsWithSuffix).data('label')); |
|||
}; |
|||
|
|||
_exprHandlers.fcall = function(expr, eventInfo) { |
|||
var oldTarget = eventInfo.targetElement; |
|||
var targets = []; |
|||
var fcallArgs = []; |
|||
var exprArgs = expr.arguments; |
|||
for(var i = 0; i < expr.arguments.length; i++) { |
|||
var exprArg = exprArgs[i]; |
|||
var fcallArg = ''; |
|||
if(targets.length) { |
|||
for(var j = 0; j < targets.length; j++) { |
|||
if(exprArg == null) { |
|||
fcallArgs[j][i] = null; |
|||
continue; |
|||
} |
|||
eventInfo.targetElement = targets[j]; |
|||
fcallArg = _evaluateExpr(exprArg, eventInfo); |
|||
if(typeof (fcallArg) == 'undefined') return ''; |
|||
fcallArgs[j][i] = fcallArg; |
|||
} |
|||
} else { |
|||
if(exprArg == null) { |
|||
fcallArgs[i] = null; |
|||
continue; |
|||
} |
|||
fcallArg = _evaluateExpr(exprArg, eventInfo); |
|||
if(typeof (fcallArg) == 'undefined') return ''; |
|||
fcallArgs[i] = fcallArg; |
|||
} |
|||
|
|||
// We do support null exprArgs...
|
|||
// TODO: This makes 2 assumptions that may change in the future. 1. The pathLiteral is the always the first arg. 2. there is always only 1 pathLiteral
|
|||
if(exprArg && exprArg.exprType == 'pathLiteral') { |
|||
targets = fcallArg; |
|||
|
|||
// fcallArgs is now an array of an array of args
|
|||
for(j = 0; j < targets.length; j++) fcallArgs[j] = [[fcallArg[j]]]; |
|||
} |
|||
} |
|||
|
|||
// we want to preserve the target element from outside this function.
|
|||
eventInfo.targetElement = oldTarget; |
|||
|
|||
var retval = ''; |
|||
if(targets.length) { |
|||
// Go backwards so retval is the first item.
|
|||
for(i = targets.length - 1; i >= 0; i--) { |
|||
var args = fcallArgs[i]; |
|||
// Add event info to the end
|
|||
args[args.length] = eventInfo; |
|||
retval = _exprFunctions[expr.functionName].apply(this, args); |
|||
} |
|||
} else fcallArgs[fcallArgs.length] = eventInfo; |
|||
return targets.length ? retval : _exprFunctions[expr.functionName].apply(this, fcallArgs); |
|||
}; |
|||
|
|||
_exprHandlers.globalVariableLiteral = function(expr) { |
|||
return expr.variableName; |
|||
}; |
|||
|
|||
_exprHandlers.keyPressLiteral = function(expr) { |
|||
var keyInfo = {}; |
|||
keyInfo.keyCode = expr.keyCode; |
|||
keyInfo.ctrl = expr.ctrl; |
|||
keyInfo.alt = expr.alt; |
|||
keyInfo.shift = expr.shift; |
|||
|
|||
return keyInfo; |
|||
}; |
|||
|
|||
_exprHandlers.adaptiveViewLiteral = function(expr) { |
|||
return expr.id; |
|||
}; |
|||
|
|||
_exprHandlers.optionLiteral = function(expr) { |
|||
return expr.value; |
|||
} |
|||
|
|||
var _substituteSTOs = function(expr, eventInfo) { |
|||
//first evaluate the local variables
|
|||
var scope = {}; |
|||
for(var varName in expr.localVariables) { |
|||
scope[varName] = $ax.expr.evaluateExpr(expr.localVariables[varName], eventInfo); |
|||
} |
|||
|
|||
// TODO: [ben] Date and data object (obj with info for url or image) both need to return non-strings.
|
|||
var i = 0; |
|||
var retval; |
|||
var retvalString = expr.value.replace(/\[\[(?!\[)(.*?)\]\](?=\]*)/g, function(match) { |
|||
var sto = expr.stos[i++]; |
|||
if(sto.sto == 'error') return match; |
|||
try { |
|||
var result = $ax.evaluateSTO(sto, scope, eventInfo); |
|||
} catch(e) { |
|||
return match; |
|||
} |
|||
|
|||
if((result instanceof Object) && i == 1 && expr.value.substring(0, 2) == '[[' && |
|||
expr.value.substring(expr.value.length - 2) == ']]') { |
|||
// If the result was an object, this was the first result, and the whole thing was this expresion.
|
|||
retval = result; |
|||
} |
|||
return ((result instanceof Object) && (result.label || result.text)) || result; |
|||
}); |
|||
// If more than one group returned, the object is not valid
|
|||
if(i != 1) retval = false; |
|||
return retval || retvalString; |
|||
}; |
|||
|
|||
_exprHandlers.htmlLiteral = function (expr, eventInfo) { |
|||
eventInfo.htmlLiteral = true; |
|||
var html = _substituteSTOs(expr, eventInfo); |
|||
eventInfo.htmlLiteral = false |
|||
return html; |
|||
}; |
|||
|
|||
_exprHandlers.stringLiteral = function(expr, eventInfo) { |
|||
return _substituteSTOs(expr, eventInfo); |
|||
}; |
|||
|
|||
var _exprFunctions = {}; |
|||
|
|||
_exprFunctions.SetCheckState = function(elementIds, value) { |
|||
var toggle = value == 'toggle'; |
|||
var boolValue = Boolean(value) && value != 'false'; |
|||
|
|||
for(var i = 0; i < elementIds.length; i++) { |
|||
var query = $ax('#' + elementIds[i]); |
|||
query.selected(toggle ? !query.selected() : boolValue); |
|||
} |
|||
}; |
|||
|
|||
_exprFunctions.SetSelectedOption = function(elementIds, value) { |
|||
for(var i = 0; i < elementIds.length; i++) { |
|||
var elementId = elementIds[i]; |
|||
var obj = $jobj($ax.INPUT(elementId)); |
|||
|
|||
if(obj.val() == value) return; |
|||
obj.val(value); |
|||
|
|||
if($ax.event.HasSelectionChanged($ax.getObjectFromElementId(elementId))) $ax.event.raiseSyntheticEvent(elementId, 'onSelectionChange'); |
|||
} |
|||
}; |
|||
|
|||
_exprFunctions.SetGlobalVariableValue = function(varName, value) { |
|||
$ax.globalVariableProvider.setVariableValue(varName, value); |
|||
}; |
|||
|
|||
_exprFunctions.SetWidgetFormText = function(elementIds, value) { |
|||
for(var i = 0; i < elementIds.length; i++) { |
|||
var elementId = elementIds[i]; |
|||
var inputId = $ax.repeater.applySuffixToElementId(elementId, '_input'); |
|||
|
|||
var obj = $jobj(inputId); |
|||
if(obj.val() == value || (value == '' && $ax.placeholderManager.isActive(elementId))) return; |
|||
obj.val(value); |
|||
$ax.placeholderManager.updatePlaceholder(elementId, !value); |
|||
if($ax.event.HasTextChanged($ax.getObjectFromElementId(elementId))) $ax.event.TryFireTextChanged(elementId); |
|||
} |
|||
}; |
|||
|
|||
_exprFunctions.SetFocusedWidgetText = function(elementId, value) { |
|||
if(window.lastFocusedControl) { |
|||
var elementId = window.lastFocusedControl; |
|||
var type = $obj(elementId).type; |
|||
if ($ax.public.fn.IsTextBox(type) || $ax.public.fn.IsTextArea(type)) _exprFunctions.SetWidgetFormText([elementId], value); |
|||
else _exprFunctions.SetWidgetRichText([elementId], value, true); |
|||
} |
|||
}; |
|||
|
|||
_exprFunctions.GetRtfElementHeight = function(rtfElement) { |
|||
if(rtfElement.innerHTML == '') rtfElement.innerHTML = ' '; |
|||
return rtfElement.offsetHeight; |
|||
}; |
|||
|
|||
_exprFunctions.SetWidgetRichText = function(ids, value, plain) { |
|||
// Converts dates, widgetinfo, and the like to strings.
|
|||
value = _exprFunctions.ToString(value); |
|||
|
|||
//Replace any newlines with line breaks
|
|||
var finalValue = value.replace(/\r\n/g, '<br>').replace(/\n/g, '<br>'); |
|||
|
|||
for(var i = 0; i < ids.length; i++) { |
|||
var id = ids[i]; |
|||
|
|||
// If calling this on button shape, get the id of the rich text panel inside instead
|
|||
if($obj(id).type !== $ax.constants.LINK_TYPE) id = $ax.GetTextPanelId(id, true); |
|||
|
|||
var element = window.document.getElementById(id); |
|||
$ax.visibility.SetVisible(element, value != ''); |
|||
|
|||
$ax.style.transformTextWithVerticalAlignment(id, function() { |
|||
var spans = $jobj(id).find('span'); |
|||
if(plain) { |
|||
// Can't set value as text because '<br/>' doesn't actually do a line break
|
|||
// Can't set vaule as html because it doesn't like '<' and ignores all after it
|
|||
// Create tags yourself
|
|||
var lines = value.split(/\r\n|\n/); |
|||
//if we are dealing with only one line, just reuse the old one
|
|||
if(spans.length === 1 && lines.length === 1) { |
|||
$(spans[0]).text(value); |
|||
return; |
|||
} |
|||
|
|||
// Wrap in span and p, style them accordingly.
|
|||
var span = $('<span></span>'); |
|||
if(spans.length > 0) { |
|||
span.attr('style', $(spans[0]).attr('style')); |
|||
span.attr('id', $(spans[0]).attr('id')); |
|||
} |
|||
|
|||
if(lines.length == 1) span.text(value); |
|||
else { |
|||
for(var i = 0; i < lines.length; i++) { |
|||
if(i != 0) span.append($('<br />')); |
|||
var line = lines[i]; |
|||
if(line.length == 0) continue; |
|||
|
|||
var subSpan = $('<span />'); |
|||
subSpan.text(line); |
|||
span.append(subSpan); |
|||
} |
|||
} |
|||
|
|||
var ps = $jobj(id).find('p'); |
|||
if(ps && ps.length) { |
|||
ps[0].innerHTML = $('<div></div>').append(span).html();; |
|||
if(ps.length > 1) { |
|||
for(var i = 1; i < ps.length; i++) { |
|||
$(ps[i]).remove(); |
|||
} |
|||
} |
|||
} else { |
|||
var p = $('<p></p>'); |
|||
p.append(span); |
|||
element.innerHTML = $('<div></div>').append(p).html(); |
|||
} |
|||
} else element.innerHTML = finalValue; |
|||
}); |
|||
|
|||
if(!plain) $ax.style.CacheOriginalText(id, true); |
|||
} |
|||
}; |
|||
|
|||
_exprFunctions.GetCheckState = function(ids) { |
|||
return $ax('#' + ids[0]).selected(); |
|||
}; |
|||
|
|||
_exprFunctions.GetDisabledState = function (ids) { |
|||
return !$ax('#' + ids[0]).enabled(); |
|||
}; |
|||
|
|||
_exprFunctions.GetSelectedOption = function (ids) { |
|||
var inputs = $jobj($ax.INPUT(ids[0])); |
|||
return inputs.length ? inputs[0].value : ''; |
|||
}; |
|||
|
|||
_exprFunctions.GetNum = function(str) { |
|||
//Setting a GlobalVariable to some blank text then setting a widget to the value of that variable would result in 0 not ""
|
|||
//I have fixed this another way so commenting this should be fine now
|
|||
//if (!str) return "";
|
|||
return isNaN(str) ? str : Number(str); |
|||
}; |
|||
|
|||
_exprFunctions.GetGlobalVariableValue = function(id) { |
|||
return $ax.globalVariableProvider.getVariableValue(id); |
|||
}; |
|||
|
|||
_exprFunctions.GetGlobalVariableLength = function(id) { |
|||
return _exprFunctions.GetGlobalVariableValue(id).length; |
|||
}; |
|||
|
|||
_exprFunctions.GetWidgetText = function(ids) { |
|||
if($ax.placeholderManager.isActive(ids[0])) return ''; |
|||
var input = $ax.INPUT(ids[0]); |
|||
return $ax('#' + ($jobj(input).length ? input : ids[0])).text(); |
|||
}; |
|||
|
|||
_exprFunctions.GetFocusedWidgetText = function() { |
|||
if(window.lastFocusedControl) { |
|||
return $ax('#' + window.lastFocusedControl).text(); |
|||
} else { |
|||
return ""; |
|||
} |
|||
}; |
|||
|
|||
_exprFunctions.GetWidgetValueLength = function(ids) { |
|||
var id = ids[0]; |
|||
if(!id) return undefined; |
|||
if($ax.placeholderManager.isActive(id)) return 0; |
|||
var obj = $jobj($ax.INPUT(id)); |
|||
if(!obj.length) obj = $jobj(id); |
|||
var val = obj[0].value || _exprFunctions.GetWidgetText([id]); |
|||
return val.length; |
|||
}; |
|||
|
|||
_exprFunctions.GetPanelState = function(ids) { |
|||
var id = ids[0]; |
|||
if(!id) return undefined; |
|||
var stateId = $ax.visibility.GetPanelState(id); |
|||
return stateId && String($jobj(stateId).data('label')); |
|||
}; |
|||
|
|||
_exprFunctions.GetWidgetVisibility = function(ids) { |
|||
var id = ids[0]; |
|||
if(!id) return undefined; |
|||
return $ax.visibility.IsIdVisible(id); |
|||
}; |
|||
|
|||
// ***************** Validation Functions ***************** //
|
|||
|
|||
_exprFunctions.IsValueAlpha = function(val) { |
|||
var isAlphaRegex = new RegExp("^[a-z\\s]+$", "gi"); |
|||
return isAlphaRegex.test(val); |
|||
}; |
|||
|
|||
_exprFunctions.IsValueNumeric = function(val) { |
|||
var isNumericRegex = new RegExp("^[0-9,\\.\\s]+$", "gi"); |
|||
return isNumericRegex.test(val); |
|||
}; |
|||
|
|||
_exprFunctions.IsValueAlphaNumeric = function(val) { |
|||
var isAlphaNumericRegex = new RegExp("^[0-9a-z\\s]+$", "gi"); |
|||
return isAlphaNumericRegex.test(val); |
|||
}; |
|||
|
|||
_exprFunctions.IsValueOneOf = function(val, values) { |
|||
for(var i = 0; i < values.length; i++) { |
|||
var option = values[i]; |
|||
if(val == option) return true; |
|||
} |
|||
//by default, return false
|
|||
return false; |
|||
}; |
|||
|
|||
_exprFunctions.IsValueNotAlpha = function(val) { |
|||
return !_exprFunctions.IsValueAlpha(val); |
|||
}; |
|||
|
|||
_exprFunctions.IsValueNotNumeric = function(val) { |
|||
return !_exprFunctions.IsValueNumeric(val); |
|||
}; |
|||
|
|||
_exprFunctions.IsValueNotAlphaNumeric = function(val) { |
|||
return !_exprFunctions.IsValueAlphaNumeric(val); |
|||
}; |
|||
|
|||
_exprFunctions.IsValueNotOneOf = function(val, values) { |
|||
return !_exprFunctions.IsValueOneOf(val, values); |
|||
}; |
|||
|
|||
_exprFunctions.GetKeyPressed = function(eventInfo) { |
|||
return eventInfo.keyInfo; |
|||
}; |
|||
|
|||
_exprFunctions.GetCursorRectangles = function() { |
|||
var rects = new Object(); |
|||
rects.lastRect = new $ax.drag.Rectangle($ax.lastMouseLocation.x, $ax.lastMouseLocation.y, 1, 1); |
|||
rects.currentRect = new $ax.drag.Rectangle($ax.mouseLocation.x, $ax.mouseLocation.y, 1, 1); |
|||
return rects; |
|||
}; |
|||
|
|||
_exprFunctions.GetWidgetRectangles = function (elementIds, eventInfo) { |
|||
var elementId = elementIds[0]; |
|||
var rects = new Object(); |
|||
var jObj = $jobj(elementId); |
|||
var invalid = jObj.length == 0; |
|||
var parent = jObj; |
|||
// Or are in valid if no obj can be found, or if it is not visible.
|
|||
while(parent.length != 0 && !parent.is('body')) { |
|||
if(parent.css('display') == 'none') { |
|||
invalid = true; |
|||
break; |
|||
} |
|||
parent = parent.parent(); |
|||
} |
|||
if(invalid) { |
|||
rects.lastRect = rects.currentRect = new $ax.drag.Rectangle(-1, -1, -1, -1); |
|||
return rects; |
|||
} |
|||
|
|||
var axObj = $ax('#' + elementId); |
|||
var boundingRect = axObj.viewportBoundingRect(); |
|||
rects.lastRect = new $ax.drag.Rectangle( |
|||
boundingRect.left, |
|||
boundingRect.top, |
|||
boundingRect.width, |
|||
boundingRect.height); |
|||
//rects.lastRect = new $ax.drag.Rectangle(
|
|||
// axObj.left(),
|
|||
// axObj.top(),
|
|||
// axObj.width(),
|
|||
// axObj.height());
|
|||
|
|||
rects.currentRect = rects.lastRect; |
|||
return rects; |
|||
}; |
|||
|
|||
_exprFunctions.GetWidget = function(elementId) { |
|||
return $ax.getWidgetInfo(elementId[0]); |
|||
}; |
|||
|
|||
_exprFunctions.GetAdaptiveView = function (eventInfo) { |
|||
if (eventInfo && eventInfo.srcElement) { |
|||
var id = eventInfo.srcElement; |
|||
var diagramObject = $ax.getObjectFromElementId(id); |
|||
if (diagramObject.owner.type == 'Axure:Master') { |
|||
var viewIdChain = $ax.style.getViewIdChain($ax.adaptive.currentViewId || '', id, diagramObject); |
|||
if (viewIdChain.length > 0) return viewIdChain[viewIdChain.length - 1]; |
|||
else return '19e82109f102476f933582835c373474'; |
|||
} |
|||
} |
|||
return $ax.adaptive.currentViewId || ''; |
|||
}; |
|||
|
|||
_exprFunctions.IsEntering = function(movingRects, targetRects) { |
|||
return !movingRects.lastRect.IntersectsWith(targetRects.currentRect) && movingRects.currentRect.IntersectsWith(targetRects.currentRect); |
|||
}; |
|||
|
|||
_exprFunctions.IsLeaving = function(movingRects, targetRects) { |
|||
return movingRects.lastRect.IntersectsWith(targetRects.currentRect) && !movingRects.currentRect.IntersectsWith(targetRects.currentRect); |
|||
}; |
|||
|
|||
var _IsOver = _exprFunctions.IsOver = function(movingRects, targetRects) { |
|||
return movingRects.currentRect.IntersectsWith(targetRects.currentRect); |
|||
}; |
|||
|
|||
_exprFunctions.IsNotOver = function(movingRects, targetRects) { |
|||
return !_IsOver(movingRects, targetRects); |
|||
}; |
|||
|
|||
_exprFunctions.ValueContains = function(inputString, value) { |
|||
return inputString.indexOf(value) > -1; |
|||
}; |
|||
|
|||
_exprFunctions.ValueNotContains = function(inputString, value) { |
|||
return !_exprFunctions.ValueContains(inputString, value); |
|||
}; |
|||
|
|||
_exprFunctions.ToString = function(value) { |
|||
if(value.isWidget) { |
|||
return value.text; |
|||
} |
|||
return String(value); |
|||
}; |
|||
|
|||
var _evaluateExpr = $ax.expr.evaluateExpr = function(expr, eventInfo, toString) { |
|||
if(expr === undefined || expr === null) return undefined; |
|||
var result = _exprHandlers[expr.exprType](expr, eventInfo); |
|||
return toString ? _exprFunctions.ToString(result) : result; |
|||
}; |
|||
|
|||
|
|||
}); |
@ -1,286 +0,0 @@ |
|||
// ******* Flyout MANAGER ******** //
|
|||
$axure.internal(function($ax) { |
|||
var _flyoutManager = $ax.flyoutManager = {}; |
|||
|
|||
var getFlyoutLabel = function(panelId) { |
|||
return panelId + '_flyout'; |
|||
}; |
|||
|
|||
var _unregisterPanel = function(panelId, keepShown) { |
|||
$ax.geometry.unregister(getFlyoutLabel(panelId)); |
|||
if(panelToSrc[panelId]) { |
|||
$ax.style.RemoveRolloverOverride(panelToSrc[panelId]); |
|||
delete panelToSrc[panelId]; |
|||
} |
|||
if(!keepShown) { |
|||
$ax.action.addAnimation(panelId, $ax.action.queueTypes.fade, function() { |
|||
$ax('#' + panelId).hide(); |
|||
}); |
|||
} |
|||
}; |
|||
_flyoutManager.unregisterPanel = _unregisterPanel; |
|||
|
|||
var genPoint = $ax.geometry.genPoint; |
|||
|
|||
var _updateFlyout = function(panelId) { |
|||
var label = getFlyoutLabel(panelId); |
|||
if(!$ax.geometry.polygonRegistered(label)) return; |
|||
var info = $ax.geometry.getPolygonInfo(label); |
|||
var rects = info && info.rects; |
|||
|
|||
var targetWidget = $ax.getWidgetInfo(panelId); |
|||
rects.target = $ax.geometry.genRect(targetWidget); |
|||
|
|||
// Src will stay the same, just updating
|
|||
$ax.flyoutManager.registerFlyout(rects, panelId, panelToSrc[panelId]); |
|||
|
|||
if(!$ax.geometry.checkInsideRegion(label)) _unregisterPanel(panelId); |
|||
}; |
|||
_flyoutManager.updateFlyout = _updateFlyout; |
|||
|
|||
var panelToSrc = {}; |
|||
var _registerFlyout = function(rects, panelId, srcId) { |
|||
var label = _getFlyoutLabel(panelId); |
|||
var callback = function(info) { |
|||
// If leaving object or already outside it, then unregister, otherwise just return
|
|||
if(!info.exiting && !info.outside) return; |
|||
_unregisterPanel(panelId); |
|||
}; |
|||
var points = []; |
|||
|
|||
var lastSrcId = panelToSrc[panelId]; |
|||
if(lastSrcId != srcId) { |
|||
if(lastSrcId) $ax.style.RemoveRolloverOverride(lastSrcId); |
|||
if(srcId) { |
|||
$ax.style.AddRolloverOverride(srcId); |
|||
panelToSrc[panelId] = srcId; |
|||
} else delete panelToSrc[panelId]; |
|||
} |
|||
|
|||
// rects should be one or two rectangles
|
|||
if(!rects.src) { |
|||
var rect = rects.target; |
|||
points.push(genPoint(rect.Left(), rect.Top())); |
|||
points.push(genPoint(rect.Right(), rect.Top())); |
|||
points.push(genPoint(rect.Right(), rect.Bottom())); |
|||
points.push(genPoint(rect.Left(), rect.Bottom())); |
|||
} else { |
|||
var r0 = rects.src; |
|||
var r1 = rects.target; |
|||
|
|||
// Right left of right, left right of left, top below top, bottom above bottom
|
|||
var rlr = r0.Right() <= r1.Right(); |
|||
var lrl = r0.Left() >= r1.Left(); |
|||
var tbt = r0.Top() >= r1.Top(); |
|||
var bab = r0.Bottom() <= r1.Bottom(); |
|||
|
|||
var info = { rlr: rlr, lrl: lrl, tbt: tbt, bab: bab }; |
|||
|
|||
if((rlr && lrl) || (tbt && bab)) { |
|||
points = getSmallPolygon(r0, r1, info); |
|||
} else { |
|||
points = getLargePolygon(r0, r1, info); |
|||
} |
|||
} |
|||
|
|||
$ax.geometry.registerPolygon(label, points, callback, { rects: rects }); |
|||
}; |
|||
_flyoutManager.registerFlyout = _registerFlyout; |
|||
|
|||
var _getFlyoutLabel = function(panelId) { |
|||
return panelId + '_flyout'; |
|||
}; |
|||
|
|||
var _reregisterAllFlyouts = function() { |
|||
for(var panelId in panelToSrc) _reregisterFlyout(panelId); |
|||
}; |
|||
_flyoutManager.reregisterAllFlyouts = _reregisterAllFlyouts; |
|||
|
|||
var _reregisterFlyout = function(panelId) { |
|||
var rects = $ax.geometry.getPolygonInfo(getFlyoutLabel(panelId)).rects; |
|||
_registerFlyout(rects, panelId, panelToSrc[panelId]); |
|||
}; |
|||
|
|||
// This is the reduced size polygon connecting r0 to r1 by means of horizontal or vertical lines.
|
|||
var getSmallPolygon = function(r0, r1, info) { |
|||
var points = []; |
|||
|
|||
// NOTE: currently I make the assumption that if horizontal/vertical connecting lines from the src hit the target
|
|||
// Meaning if horizontal, rlr and lrl are true, and if vertical, tbt and bab are true.
|
|||
|
|||
var r0Left = r0.Left(); |
|||
var r0Right = r0.Right(); |
|||
var r0Top = r0.Top(); |
|||
var r0Bottom = r0.Bottom(); |
|||
var r1Left = r1.Left(); |
|||
var r1Right = r1.Right(); |
|||
var r1Top = r1.Top(); |
|||
var r1Bottom = r1.Bottom(); |
|||
|
|||
points.push(genPoint(r1Left, r1Top)); |
|||
|
|||
if(!info.tbt) { |
|||
points.push(genPoint(r0Left, r1Top)); |
|||
points.push(genPoint(r0Left, r0Top)); |
|||
points.push(genPoint(r0Right, r0Top)); |
|||
points.push(genPoint(r0Right, r1Top)); |
|||
} |
|||
|
|||
points.push(genPoint(r1Right, r1Top)); |
|||
|
|||
if(!info.rlr) { |
|||
points.push(genPoint(r1Right, r0Top)); |
|||
points.push(genPoint(r0Right, r0Top)); |
|||
points.push(genPoint(r0Right, r0Bottom)); |
|||
points.push(genPoint(r1Right, r0Bottom)); |
|||
} |
|||
|
|||
points.push(genPoint(r1Right, r1Bottom)); |
|||
|
|||
if(!info.bab) { |
|||
points.push(genPoint(r0Right, r1Bottom)); |
|||
points.push(genPoint(r0Right, r0Bottom)); |
|||
points.push(genPoint(r0Left, r0Bottom)); |
|||
points.push(genPoint(r0Left, r1Bottom)); |
|||
} |
|||
|
|||
points.push(genPoint(r1Left, r1Bottom)); |
|||
|
|||
if(!info.lrl) { |
|||
points.push(genPoint(r1Left, r0Bottom)); |
|||
points.push(genPoint(r0Left, r0Bottom)); |
|||
points.push(genPoint(r0Left, r0Top)); |
|||
points.push(genPoint(r1Left, r0Top)); |
|||
} |
|||
|
|||
return points; |
|||
}; |
|||
|
|||
// This is the original algorithm that connects the most extream corners to make polygon
|
|||
var getLargePolygon = function(r0, r1, info) { |
|||
var points = []; |
|||
|
|||
var r0Left = r0.Left(); |
|||
var r0Right = r0.Right(); |
|||
var r0Top = r0.Top(); |
|||
var r0Bottom = r0.Bottom(); |
|||
var r1Left = r1.Left(); |
|||
var r1Right = r1.Right(); |
|||
var r1Top = r1.Top(); |
|||
var r1Bottom = r1.Bottom(); |
|||
|
|||
// Top lefts
|
|||
if(info.tbt) { |
|||
if(!info.lrl) points.push(genPoint(r0Left, r0Top)); |
|||
points.push(genPoint(r1Left, r1Top)); |
|||
} else { |
|||
if(info.lrl) points.push(genPoint(r1Left, r1Top)); |
|||
points.push(genPoint(r0Left, r0Top)); |
|||
} |
|||
|
|||
// Top rights
|
|||
if(info.tbt) { |
|||
points.push(genPoint(r1Right, r1Top)); |
|||
if(!info.rlr) points.push(genPoint(r0Right, r0Top)); |
|||
} else { |
|||
points.push(genPoint(r0Right, r0Top)); |
|||
if(info.rlr) points.push(genPoint(r1Right, r1Top)); |
|||
} |
|||
|
|||
// Bottom rights
|
|||
if(info.bab) { |
|||
if(!info.rlr) points.push(genPoint(r0Right, r0Bottom)); |
|||
points.push(genPoint(r1Right, r1Bottom)); |
|||
} else { |
|||
if(info.rlr) points.push(genPoint(r1Right, r1Bottom)); |
|||
points.push(genPoint(r0Right, r0Bottom)); |
|||
} |
|||
|
|||
// Bottom Lefts
|
|||
if(info.bab) { |
|||
points.push(genPoint(r1Left, r1Bottom)); |
|||
if(!info.lrl) points.push(genPoint(r0Left, r0Bottom)); |
|||
} else { |
|||
points.push(genPoint(r0Left, r0Bottom)); |
|||
if(info.lrl) points.push(genPoint(r1Left, r1Bottom)); |
|||
} |
|||
return points; |
|||
}; |
|||
}); |
|||
|
|||
// ******* Placeholder Manager ********* //
|
|||
|
|||
$axure.internal(function($ax) { |
|||
var _placeholderManager = $ax.placeholderManager = {}; |
|||
var idToPlaceholderInfo = {}; |
|||
|
|||
var _registerPlaceholder = function(elementId, text, password) { |
|||
idToPlaceholderInfo[elementId] = { text: text, password: password, active: false }; |
|||
}; |
|||
_placeholderManager.registerPlaceholder = _registerPlaceholder; |
|||
|
|||
_placeholderManager.refreshPlaceholder = function (elementId) { |
|||
var info = idToPlaceholderInfo[elementId]; |
|||
if (!info || !info.active) return; |
|||
$ax.style.SetWidgetPlaceholder(elementId, true, info.text, info.password); |
|||
} |
|||
|
|||
var _updatePlaceholder = function(elementId, active, clearText) { |
|||
var inputId = $ax.repeater.applySuffixToElementId(elementId, '_input'); |
|||
|
|||
var info = idToPlaceholderInfo[elementId]; |
|||
if(!info || info.active == active) return; |
|||
info.active = active; |
|||
|
|||
if(active) var text = info.text; |
|||
else if(!ANDROID) text = clearText ? '' : document.getElementById(inputId).value; |
|||
else { |
|||
var currentText = document.getElementById(inputId).value; |
|||
if(!clearText) text = currentText; |
|||
else if(currentText == info.text) text = ""; |
|||
else { |
|||
var lastIndex = currentText.lastIndexOf(info.text); |
|||
//here i am assuming the text is always inserted in front
|
|||
text = currentText.substring(0, lastIndex); |
|||
} |
|||
} |
|||
|
|||
$ax.style.SetWidgetPlaceholder(elementId, active, text, info.password); |
|||
}; |
|||
_placeholderManager.updatePlaceholder = _updatePlaceholder; |
|||
|
|||
var _isActive = function(elementId) { |
|||
var info = idToPlaceholderInfo[elementId]; |
|||
return Boolean(info && info.active); |
|||
}; |
|||
_placeholderManager.isActive = _isActive; |
|||
|
|||
var _selectRange = function(elementId, start, end) { |
|||
$jobj(elementId).each(function() { |
|||
if(this.setSelectionRange) { |
|||
var validTypes = ["text", "search", "url", "tel", "password"]; |
|||
if(this.tagName.toLowerCase() != "input" || validTypes.indexOf(this.type) > -1) { |
|||
this.focus(); |
|||
this.setSelectionRange(start, end); |
|||
} |
|||
} else if(this.createTextRange) { |
|||
var range = this.createTextRange(); |
|||
range.collapse(true); |
|||
range.moveEnd('character', end); |
|||
range.moveStart('character', start); |
|||
range.select(); |
|||
} |
|||
}); |
|||
}; |
|||
_placeholderManager.selectRange = _selectRange; |
|||
|
|||
var _moveCaret = function(id, index) { |
|||
var inputIndex = id.indexOf('_input'); |
|||
if(inputIndex == -1) return; |
|||
var inputId = id.substring(0, inputIndex); |
|||
|
|||
if(!_isActive(inputId)) return; |
|||
_selectRange(id, index, index); |
|||
}; |
|||
_placeholderManager.moveCaret = _moveCaret; |
|||
}); |
@ -1,294 +0,0 @@ |
|||
// ******* Region MANAGER ******** //
|
|||
$axure.internal(function($ax) { |
|||
var _geometry = $ax.geometry = {}; |
|||
var regionMap = {}; |
|||
var regionList = []; |
|||
|
|||
var _unregister = function(label) { |
|||
var regionIndex = regionList.indexOf(label); |
|||
if(regionIndex != -1) { |
|||
var end = $ax.splice(regionList, regionIndex + 1); |
|||
$ax.splice(regionList, regionIndex, regionList.length - regionIndex); |
|||
regionList = regionList.concat(end); |
|||
} |
|||
delete regionMap[label]; |
|||
}; |
|||
_geometry.unregister = _unregister; |
|||
|
|||
var clear = function() { |
|||
regionMap = {}; |
|||
regionList = []; |
|||
}; |
|||
|
|||
var _polygonRegistered = function(label) { |
|||
return Boolean(regionMap[label]); |
|||
}; |
|||
_geometry.polygonRegistered = _polygonRegistered; |
|||
|
|||
// Must be counterclockwise, or enter/exit will be wrong
|
|||
var _registerPolygon = function(label, points, callback, info) { |
|||
var regionIndex = regionList.indexOf(label); |
|||
if(regionIndex == -1) regionList.push(label); |
|||
regionMap[label] = { points: points, callback: callback, info: info }; |
|||
}; |
|||
_geometry.registerPolygon = _registerPolygon; |
|||
|
|||
var _getPolygonInfo = function(label) { |
|||
if(!_polygonRegistered(label)) return undefined; |
|||
return regionMap[label].info; |
|||
}; |
|||
_geometry.getPolygonInfo = _getPolygonInfo; |
|||
|
|||
|
|||
|
|||
var _genRect = function(info, roundHalfPixel) { |
|||
var x = info.pagex(); |
|||
var y = info.pagey(); |
|||
var w = info.width(); |
|||
var h = info.height(); |
|||
|
|||
if(roundHalfPixel) { |
|||
if(x % 1 != 0) { |
|||
x = Math.floor(x); |
|||
w++; |
|||
} |
|||
if(y % 1 != 0) { |
|||
y = Math.floor(y); |
|||
h++; |
|||
} |
|||
} |
|||
|
|||
var r = x + w; |
|||
var b = y + h; |
|||
|
|||
var rect = { |
|||
X: function() { return x; }, |
|||
Y: function() { return y; }, |
|||
Wigth: function() { return w; }, |
|||
Height: function() { return h; }, |
|||
Left: function() { return x; }, |
|||
Right: function() { return r; }, |
|||
Top: function() { return y; }, |
|||
Bottom: function() { return b; } |
|||
}; |
|||
return rect; |
|||
}; |
|||
_geometry.genRect = _genRect; |
|||
|
|||
var _genPoint = function(x, y) { |
|||
return { x: x, y: y }; |
|||
}; |
|||
_geometry.genPoint = _genPoint; |
|||
|
|||
var oldPoint = _genPoint(0, 0); |
|||
_geometry.tick = function(x, y, end) { |
|||
var lastPoint = oldPoint; |
|||
var nextPoint = oldPoint = _genPoint(x, y); |
|||
var line = { p1: lastPoint, p2: nextPoint }; |
|||
if(!regionList.length) return; |
|||
|
|||
for(var i = 0; i < regionList.length; i++) { |
|||
var region = regionMap[regionList[i]]; |
|||
var points = region.points; |
|||
for(var j = 0; j < points.length; j++) { |
|||
var startSegment = points[j]; |
|||
var endSegment = points[(j + 1) % points.length]; |
|||
var intersectInfo = linesIntersect(line, { p1: startSegment, p2: endSegment }); |
|||
if(intersectInfo) { |
|||
region.callback(intersectInfo); |
|||
break; |
|||
} |
|||
} |
|||
} |
|||
|
|||
if(end) clear(); |
|||
}; |
|||
|
|||
// Info if the one line touches the other (even barely), false otherwise
|
|||
// Info includes point, if l1 is entering or exiting l2, and any ties that happened, or parallel info
|
|||
var linesIntersect = function(l1, l2) { |
|||
var retval = {}; |
|||
var ties = {}; |
|||
|
|||
var l1p1 = l1.p1.x < l1.p2.x || (l1.p1.x == l1.p2.x && l1.p1.y < l1.p2.y) ? l1.p1 : l1.p2; |
|||
var l1p2 = l1.p1.x < l1.p2.x || (l1.p1.x == l1.p2.x && l1.p1.y < l1.p2.y) ? l1.p2 : l1.p1; |
|||
var m1 = (l1p2.y - l1p1.y) / (l1p2.x - l1p1.x); |
|||
|
|||
var l2p1 = l2.p1.x < l2.p2.x || (l2.p1.x == l2.p2.x && l2.p1.y < l2.p2.y) ? l2.p1 : l2.p2; |
|||
var l2p2 = l2.p1.x < l2.p2.x || (l2.p1.x == l2.p2.x && l2.p1.y < l2.p2.y) ? l2.p2 : l2.p1; |
|||
var m2 = (l2p2.y - l2p1.y) / (l2p2.x - l2p1.x); |
|||
|
|||
var l1Vert = l1.p1.x == l1.p2.x; |
|||
var l2Vert = l2.p1.x == l2.p2.x; |
|||
if(l1Vert || l2Vert) { |
|||
if(l1Vert && l2Vert) { |
|||
// If the lines don't follow the same path, return
|
|||
if(l1p1.x != l2p1.x) return false; |
|||
// if they never meet, return
|
|||
if(l1p2.y < l2p1.y || l1p1.y > l2p2.y) return false; |
|||
var firstVert = l1p1.y >= l2p1.y ? l1p1 : l2p1; |
|||
var secondVert = l1p2.y <= l2p2.y ? l1p2 : l2p2; |
|||
// First is from the perspective of l1
|
|||
retval.parallel = { |
|||
first: l1p1 == l1.p1 ? firstVert : secondVert, |
|||
second: l1p2 == l1.p2 ? secondVert : firstVert, |
|||
sameDirection: (l1p1 == l1.p1) == (l2p1 == l2.p1) |
|||
}; |
|||
|
|||
return retval; |
|||
} |
|||
|
|||
var x1 = l2Vert ? l1p1.x : l2p1.x; |
|||
var x2 = l2Vert ? l1p2.x : l2p2.x; |
|||
var xVert = l2Vert ? l2p1.x : l1p1.x; |
|||
|
|||
var y = l2Vert ? l1p1.y + (xVert - x1) * m1 : l2p1.y + (xVert - x1) * m2; |
|||
var y1 = l2Vert ? l2p1.y : l1p1.y; |
|||
var y2 = l2Vert ? l2p2.y : l1p2.y; |
|||
if(xVert >= x1 && xVert <= x2 && y >= y1 && y <= y2) { |
|||
retval.point = { x: xVert, y: y }; |
|||
retval.exiting = l2Vert == (y1 == (l2Vert ? l2.p1.y : l1.p1.y)) == (x1 == (l2Vert ? l1.p1.x : l2.p1.x)); |
|||
retval.entering = !retval.exiting; |
|||
|
|||
// Calculate ties
|
|||
if(x1 == xVert) { |
|||
ties[l2Vert ? 'l1' : 'l2'] = (x1 == (l2Vert ? l1.p1.x : l2.p1.x)) ? 'start' : 'end'; |
|||
retval.ties = ties; |
|||
} else if(x2 == xVert) { |
|||
ties[l2Vert ? 'l1' : 'l2'] = (x2 == (l2Vert ? l1.p2.x : l2.p2.x)) ? 'end' : 'start'; |
|||
retval.ties = ties; |
|||
} |
|||
if(y1 == y) { |
|||
ties[l2Vert ? 'l2' : 'l1'] = (y1 == (l2Vert ? l2.p1.y : l1.p1.y)) ? 'start' : 'end'; |
|||
retval.ties = ties; |
|||
} else if(y2 == y) { |
|||
ties[l2Vert ? 'l2' : 'l1'] = (y2 == (l2Vert ? l2.p2.y : l1.p2.y)) ? 'end' : 'start'; |
|||
retval.ties = ties; |
|||
} |
|||
|
|||
return retval; |
|||
} |
|||
return false; |
|||
} |
|||
// If here, no vertical lines
|
|||
|
|||
if(m1 == m2) { |
|||
// If the lines don't follow the same path, return
|
|||
if(l1p1.y != (l2p1.y + (l1p1.x - l2p1.x) * m1)) return false; |
|||
// if they never meet, return
|
|||
if(l1p2.x < l2p1.x || l1p1.x > l2p2.x) return false; |
|||
var first = l1p1.x >= l2p1.x ? l1p1 : l2p1; |
|||
var second = l1p2.x <= l2p2.x ? l1p2 : l2p2; |
|||
// First is from the perspective of l1
|
|||
retval.parallel = { |
|||
first: l1p1 == l1.p1 ? first : second, |
|||
second: l1p2 == l1.p2 ? second : first, |
|||
sameDirection: (l1p1 == l1.p1) == (l2p1 == l2.p1) |
|||
}; |
|||
|
|||
return retval; |
|||
} |
|||
|
|||
var x = (l2p1.y - l2p1.x * m2 - l1p1.y + l1p1.x * m1) / (m1 - m2); |
|||
|
|||
// Check if x is out of bounds
|
|||
if(x >= l1p1.x && x <= l1p2.x && x >= l2p1.x && x <= l2p2.x) { |
|||
var y = l1p1.y + (x - l1p1.x) * m1; |
|||
retval.point = { x: x, y: y }; |
|||
retval.entering = m1 > m2 == (l1p1 == l1.p1) == (l2p1 == l2.p1); |
|||
retval.exiting = !retval.entering; |
|||
|
|||
// Calculate ties
|
|||
if(l1.p1.x == x) { |
|||
ties.l1 = 'start'; |
|||
retval.ties = ties; |
|||
} else if(l1.p2.x == x) { |
|||
ties.l1 = 'end'; |
|||
retval.ties = ties; |
|||
} |
|||
if(l2.p1.x == x) { |
|||
ties.l2 = 'start'; |
|||
retval.ties = ties; |
|||
} else if(l2.p2.x == x) { |
|||
ties.l2 = 'end'; |
|||
retval.ties = ties; |
|||
} |
|||
|
|||
return retval; |
|||
} |
|||
return false; |
|||
}; |
|||
|
|||
var _checkInsideRegion = function(label, point) { |
|||
if(!_polygonRegistered(label)) return false; |
|||
|
|||
return _checkInside(regionMap[label].points, point || $ax.mouseLocation); |
|||
}; |
|||
_geometry.checkInsideRegion = _checkInsideRegion; |
|||
|
|||
// Returns true if point is inside the polygon, including ties
|
|||
var _checkInside = function(polygon, point) { |
|||
// Make horizontal line wider than the polygon, with the y of point to test location
|
|||
var firstX = polygon[0].x; |
|||
var secondX = firstX; |
|||
var i; |
|||
for(i = 1; i < polygon.length; i++) { |
|||
var polyX = polygon[i].x; |
|||
firstX = Math.min(firstX, polyX); |
|||
secondX = Math.max(secondX, polyX); |
|||
} |
|||
var line = { |
|||
p1: _genPoint(--firstX, point.y), |
|||
p2: _genPoint(++secondX, point.y) |
|||
}; |
|||
|
|||
// If entered true, with closest intersection says you are inside the polygon.
|
|||
var entered = false; |
|||
// Closest is the closest intersection to the left of the point
|
|||
var closest = line.p1.x; |
|||
// This is for if intersections hit the same point, to find out which is correct
|
|||
var cos = -2; |
|||
|
|||
var getCos = function(line) { |
|||
var x = line.p2.x - line.p1.x; |
|||
var y = line.p2.y - line.p1.y; |
|||
return x / Math.sqrt(x * x + y * y); |
|||
}; |
|||
|
|||
for(i = 0; i < polygon.length; i++) { |
|||
var polyLine = { p1: polygon[i], p2: polygon[(i + 1) % polygon.length] }; |
|||
var intersectInfo = linesIntersect(line, polyLine); |
|||
if(!intersectInfo) continue; |
|||
|
|||
if(intersectInfo.parallel) { |
|||
// Only really care about this if it actually touches the point
|
|||
if(intersectInfo.parallel.first.x <= point.x && intersectInfo.parallel.second.x >= point.x) return true; |
|||
continue; |
|||
} |
|||
|
|||
var intersectionX = intersectInfo.point.x; |
|||
if(intersectionX > point.x || intersectionX < closest) continue; |
|||
if(intersectionX == point.x) return true; |
|||
|
|||
// If closer than last time, reset cosine.
|
|||
if(intersectionX != closest) cos = -2; |
|||
|
|||
// For getting cosine, need to possibly reverse the direction of polyLine.
|
|||
if(intersectInfo.ties) { |
|||
// Tie must be on l2, if the ties is end, reverse so cosine indicates how close the angle is to that of 'point' from here.
|
|||
if(intersectInfo.ties.l2 == 'end') polyLine = { p1: polyLine.p2, p2: polyLine.p1 }; |
|||
} else { |
|||
// It is on both side, so you can take the larger one
|
|||
if(polyLine.p1.x > polyLine.p2.x) polyLine = { p1: polyLine.p2, p2: polyLine.p1 }; |
|||
} |
|||
var currCos = getCos(polyLine); |
|||
if(currCos > cos) { |
|||
cos = currCos; |
|||
closest = intersectionX; |
|||
entered = intersectInfo.entering; |
|||
} |
|||
} |
|||
return entered; |
|||
}; |
|||
_geometry.checkInside = _checkInside; |
|||
}); |
@ -1,7 +0,0 @@ |
|||
$axure.internal(function($ax) { |
|||
var _globals = $ax.globals = {}; |
|||
|
|||
$ax.globals.MaxZIndex = 1000; |
|||
$ax.globals.MinZIndex = -1000; |
|||
|
|||
}); |
@ -1,344 +0,0 @@ |
|||
|
|||
//// ******* Internet Explorer MANAGER ******** //
|
|||
////this is to handle all the stupid IE Stuff
|
|||
//$axure.internal(function($ax) {
|
|||
// if(!IE_10_AND_BELOW) return;
|
|||
|
|||
// var _ieColorManager = {};
|
|||
// if(Number(BROWSER_VERSION) < 9) $ax.ieColorManager = _ieColorManager;
|
|||
|
|||
// var _applyIEFixedPosition = function() {
|
|||
// if(Number(BROWSER_VERSION) >= 7) return;
|
|||
|
|||
// $axure(function(diagramObject) { return diagramObject.fixedVertical; }).$()
|
|||
// .appendTo($('body'))
|
|||
// .css('position', 'absolute').css('margin-left', 0 + 'px').css('margin-top', 0 + 'px');
|
|||
|
|||
// var handleScroll = function() {
|
|||
// $axure(function(diagramObject) { return diagramObject.fixedVertical; })
|
|||
// .each(function(diagramObject, elementId) {
|
|||
// var win = $(window);
|
|||
// var windowWidth = win.width();
|
|||
// var windowHeight = win.height();
|
|||
// var windowScrollLeft = win.scrollLeft();
|
|||
// var windowScrollTop = win.scrollTop();
|
|||
|
|||
// var newLeft = 0;
|
|||
// var newTop = 0;
|
|||
// var elementQuery = $('#' + elementId);
|
|||
// var elementAxQuery = $ax('#' + elementId);
|
|||
// var width = elementAxQuery.width();
|
|||
// var height = elementAxQuery.height();
|
|||
|
|||
// var horz = diagramObject.fixedHorizontal;
|
|||
// if(horz == 'left') {
|
|||
// newLeft = windowScrollLeft + diagramObject.fixedMarginHorizontal;
|
|||
// } else if(horz == 'center') {
|
|||
// newLeft = windowScrollLeft + ((windowWidth - width) / 2) + diagramObject.fixedMarginHorizontal;
|
|||
// } else if(horz == 'right') {
|
|||
// newLeft = windowScrollLeft + windowWidth - width - diagramObject.fixedMarginHorizontal;
|
|||
// }
|
|||
|
|||
// var vert = diagramObject.fixedVertical;
|
|||
// if(vert == 'top') {
|
|||
// newTop = windowScrollTop + diagramObject.fixedMarginVertical;
|
|||
// } else if(vert == 'middle') {
|
|||
// newTop = windowScrollTop + ((windowHeight - height) / 2) + diagramObject.fixedMarginVertical;
|
|||
// } else if(vert == 'bottom') {
|
|||
// newTop = windowScrollTop + windowHeight - height - diagramObject.fixedMarginVertical;
|
|||
// }
|
|||
// elementQuery.css('top', newTop + 'px').css('left', newLeft + 'px');
|
|||
// });
|
|||
// };
|
|||
|
|||
// $(window).scroll(handleScroll);
|
|||
// $axure.resize(handleScroll);
|
|||
// handleScroll();
|
|||
// };
|
|||
|
|||
// var _applyBackground = function() {
|
|||
// if(Number(BROWSER_VERSION) >= 9) return;
|
|||
|
|||
// var styleChain = $ax.adaptive.getAdaptiveIdChain($ax.adaptive.currentViewId);
|
|||
// var argb = _getArgb($ax.pageData.page, styleChain);
|
|||
// var hexColor = _getHexColor(argb, false);
|
|||
// if(hexColor) $('body').css('background-color', hexColor);
|
|||
|
|||
// _applyBackgroundToQuery($ax('*'));
|
|||
// };
|
|||
|
|||
// var _applyBackgroundToQuery = function(query) {
|
|||
// if(Number(BROWSER_VERSION) >= 9) return;
|
|||
|
|||
// var styleChain = $ax.adaptive.getAdaptiveIdChain($ax.adaptive.currentViewId);
|
|||
// query.each(function(obj, elementId) {
|
|||
// if ($ax.public.fn.IsDynamicPanel(obj.type)) {
|
|||
// var stateCount = obj.diagrams.length;
|
|||
// for(var j = 0; j < stateCount; j++) {
|
|||
// var stateId = $ax.repeater.applySuffixToElementId(elementId, '_state' + j);
|
|||
// var argb = _getArgb(obj.diagrams[j], styleChain);
|
|||
// var hexColor = _getHexColor(argb, true);
|
|||
// if(hexColor) $jobj(stateId).css('background-color', hexColor);
|
|||
// }
|
|||
// } else if ($ax.public.fn.IsRepeater(obj.type)) {
|
|||
|
|||
// }
|
|||
// });
|
|||
// };
|
|||
// _ieColorManager.applyBackground = _applyBackgroundToQuery;
|
|||
|
|||
// var _getArgb = function(diagram, styleChain) {
|
|||
// var argb = undefined;
|
|||
// for(var i = 0; i < styleChain.length && !argb; i++) {
|
|||
// var style = diagram.adaptiveStyles[styleChain[i]];
|
|||
// argb = style.fill && style.fill.color;
|
|||
// }
|
|||
// if(!argb) argb = diagram.style.fill.color;
|
|||
// return argb;
|
|||
// };
|
|||
|
|||
// var gMult = 256;
|
|||
// var rMult = gMult * 256;
|
|||
// var aMult = rMult * 256;
|
|||
|
|||
// var _getHexColor = function(argb, allowWhite) {
|
|||
// var a = Math.floor(argb / aMult);
|
|||
// argb -= a * aMult;
|
|||
|
|||
// var r = Math.floor(argb / rMult);
|
|||
// argb -= r * rMult;
|
|||
|
|||
// var g = Math.floor(argb / gMult);
|
|||
// var b = argb - g * gMult;
|
|||
|
|||
// return _getColorFromArgb(a, r, g, b, allowWhite);
|
|||
// };
|
|||
|
|||
// var _getColorFromArgb = function(a, r, g, b, allowWhite) {
|
|||
// if(Number(BROWSER_VERSION) >= 9) return undefined;
|
|||
|
|||
// //convert the color with alpha to a color with no alpha (assuming white background)
|
|||
// r = Math.min((r * a) / 255 + 255 - a, 255);
|
|||
// g = Math.min((g * a) / 255 + 255 - a, 255);
|
|||
// b = Math.min((b * a) / 255 + 255 - a, 255);
|
|||
|
|||
// if(a == 0) return undefined;
|
|||
// if(!allowWhite && (r == 255 && g == 255 && b == 255)) return undefined;
|
|||
|
|||
// var color = '#';
|
|||
// color += Math.floor(r / 16).toString(16);
|
|||
// color += Math.floor(r % 16).toString(16);
|
|||
// color += Math.floor(g / 16).toString(16);
|
|||
// color += Math.floor(g % 16).toString(16);
|
|||
// color += Math.floor(b / 16).toString(16);
|
|||
// color += Math.floor(b % 16).toString(16);
|
|||
// return color;
|
|||
// };
|
|||
// _ieColorManager.getColorFromArgb = _getColorFromArgb;
|
|||
|
|||
// var getIEOffset = function(transform, rect) {
|
|||
// var translatedVertexes = [
|
|||
// $axure.utils.Vector2D(0, 0), //we dont translate, so the orgin is fixed
|
|||
// transform.mul($axure.utils.Vector2D(0, rect.height)),
|
|||
// transform.mul($axure.utils.Vector2D(rect.width, 0)),
|
|||
// transform.mul($axure.utils.Vector2D(rect.width, rect.height))];
|
|||
|
|||
// var minX = 0, minY = 0, maxX = 0, maxY = 0;
|
|||
// $.each(translatedVertexes, function(index, p) {
|
|||
// minX = Math.min(minX, p.x);
|
|||
// minY = Math.min(minY, p.y);
|
|||
// maxX = Math.max(maxX, p.x);
|
|||
// maxY = Math.max(maxY, p.y);
|
|||
// });
|
|||
|
|||
// return $axure.utils.Vector2D(
|
|||
// (maxX - minX - rect.width) / 2,
|
|||
// (maxY - minY - rect.height) / 2);
|
|||
// };
|
|||
|
|||
// var _filterFromTransform = function(transform) {
|
|||
// return "progid:DXImageTransform.Microsoft.Matrix(M11=" + transform.m11 +
|
|||
// ", M12=" + transform.m12 + ", M21=" + transform.m21 +
|
|||
// ", M22=" + transform.m22 + ", SizingMethod='auto expand')";
|
|||
// };
|
|||
|
|||
// var _applyIERotation = function() {
|
|||
// if(Number(BROWSER_VERSION) >= 9) return;
|
|||
|
|||
// $axure(function(diagramObject) {
|
|||
// return ((diagramObject.style.rotation && Math.abs(diagramObject.style.rotation) > 0.1)
|
|||
// || (diagramObject.style.textRotation && Math.abs(diagramObject.style.textRotation) > 0.1))
|
|||
// && !diagramObject.isContained;
|
|||
// }).each(function(diagramObject, elementId) {
|
|||
// var rotation = diagramObject.style.rotation || 0;
|
|||
// var $element = $('#' + elementId);
|
|||
// var axElement = $ax('#' + elementId);
|
|||
// var width = axElement.width();
|
|||
// var height = axElement.height();
|
|||
// var originX = width / 2;
|
|||
// var originY = height / 2;
|
|||
|
|||
// var shapeIeOffset;
|
|||
// $element.children().each(function() {
|
|||
// var $child = $(this);
|
|||
// var axChild = $ax('#' + $child.attr('id'));
|
|||
// var childWidth = axChild.width();
|
|||
// var childHeight = axChild.height() + $child.position().top;
|
|||
// var centerX = $child.position().left + (childWidth / 2);
|
|||
// var centerY = $child.position().top + (childHeight / 2);
|
|||
// var deltaX = centerX - originX;
|
|||
// var deltaY = centerY - originY;
|
|||
|
|||
// var effectiveRotation = rotation;
|
|||
// var textObject = $ax.getObjectFromElementId($child.attr('id'));
|
|||
// if(textObject) {
|
|||
// if(textObject.style.textRotation) effectiveRotation = textObject.style.textRotation;
|
|||
// else return;
|
|||
// }
|
|||
|
|||
// var transform = $ax.utils.Matrix2D.identity().rotate(effectiveRotation);
|
|||
// var filter = _filterFromTransform(transform);
|
|||
|
|||
// $child.css('filter', filter)
|
|||
// .width(childWidth + 1)
|
|||
// .height(childHeight + 1);
|
|||
|
|||
// var p = transform.mul($ax.utils.Vector2D(deltaX, deltaY));
|
|||
// var ieOffset = getIEOffset(transform, { width: childWidth, height: childHeight });
|
|||
// if(!textObject) {
|
|||
// shapeIeOffset = ieOffset;
|
|||
// } else {
|
|||
// // This is a close approximation, but not exact
|
|||
// if(diagramObject.style.verticalAlignment != 'top') ieOffset.y -= shapeIeOffset.y + Math.abs(shapeIeOffset.x);
|
|||
// }
|
|||
|
|||
// $child.css("margin-left", -ieOffset.x - deltaX + p.x).css("margin-top", -ieOffset.y - deltaY + p.y);
|
|||
// });
|
|||
// });
|
|||
// };
|
|||
|
|||
// var _fixIEStretchBackground = function() {
|
|||
// if(Number(BROWSER_VERSION) >= 9) return;
|
|||
// var pageStyle = $ax.adaptive.getPageStyle();
|
|||
// if(!pageStyle.imageRepeat || pageStyle.imageRepeat == 'auto') return;
|
|||
|
|||
// $('body').css('background-image', 'none');
|
|||
// var viewId = $ax.adaptive.currentViewId;
|
|||
// var imageInfo = viewId ? $ax.pageData.viewIdToBackgroundImageInfo && $ax.pageData.viewIdToBackgroundImageInfo[viewId] : $ax.pageData.defaultBackgroundImageInfo;
|
|||
// if(imageInfo && imageInfo.path) {
|
|||
// if($('#bg_img').length == 0) $('body').append('<img id="bg_img"/>');
|
|||
// $('#bg_img').attr('src', imageInfo.path).css('position', 'fixed').css('z-index', '-10000');
|
|||
// _resizeIEBackground();
|
|||
// } else $('#bg_img').remove();
|
|||
// };
|
|||
|
|||
// var _resizeIEBackground = function() {
|
|||
// if(Number(BROWSER_VERSION) >= 9) return;
|
|||
// //var page = $ax.pageData.page;
|
|||
// var viewId = $ax.adaptive.currentViewId;
|
|||
// var pageStyle = $ax.adaptive.getPageStyle();
|
|||
// if(!$ax.pageData.defaultBackgroundImageInfo && !$ax.pageData.viewIdToBackgroundImageInfo) return;
|
|||
// var imageInfo = viewId ? $ax.pageData.viewIdToBackgroundImageInfo[viewId] : $ax.pageData.defaultBackgroundImageInfo;
|
|||
// if(!imageInfo) return;
|
|||
// var imageWidth = imageInfo.width;
|
|||
// var imageHeight = imageInfo.height;
|
|||
// var windowWidth = $(window).width();
|
|||
// var windowHeight = $(window).height();
|
|||
// var isCover = pageStyle.imageRepeat == 'cover';
|
|||
|
|||
// var wRatio = windowWidth / imageWidth;
|
|||
// var hRatio = windowHeight / imageHeight;
|
|||
// var ratio = wRatio;
|
|||
// if(isCover) {
|
|||
// if(hRatio > wRatio) ratio = hRatio;
|
|||
// } else {
|
|||
// if(hRatio < wRatio) ratio = hRatio;
|
|||
// }
|
|||
// var width = imageWidth * ratio;
|
|||
// var height = imageHeight * ratio;
|
|||
|
|||
// var left = '0px';
|
|||
// if((isCover && width > windowWidth) || (!isCover && width < windowWidth)) {
|
|||
// if(pageStyle.imageHorizontalAlignment == 'center') {
|
|||
// left = ((windowWidth - width) / 2) + 'px';
|
|||
// } else if(pageStyle.imageHorizontalAlignment == 'far') {
|
|||
// left = (windowWidth - width) + 'px';
|
|||
// }
|
|||
// }
|
|||
|
|||
// var top = '0px';
|
|||
// if((isCover && height > windowHeight) || (!isCover && height < windowHeight)) {
|
|||
// if(pageStyle.imageVerticalAlignment == 'center') {
|
|||
// top = ((windowHeight - height) / 2) + 'px';
|
|||
// } else if(pageStyle.imageVerticalAlignment == 'far') {
|
|||
// top = (windowHeight - height) + 'px';
|
|||
// }
|
|||
// }
|
|||
|
|||
// $('#bg_img').css('top', top).css('left', left).css('width', width).css('height', height);
|
|||
// };
|
|||
|
|||
// var _fixAllPngs = function() {
|
|||
// if(!(/MSIE ((5\.5)|6)/.test(window.navigator.userAgent) && window.navigator.platform == "Win32")) return;
|
|||
|
|||
// $('img[src$=".png"]').each(function() {
|
|||
// if(!this.complete) {
|
|||
// this.onload = function() { $axure.utils.fixPng(this); };
|
|||
// } else {
|
|||
// $axure.utils.fixPng(this);
|
|||
// }
|
|||
// });
|
|||
// };
|
|||
|
|||
// var _fixInputSize = function() {
|
|||
// if(Number(BROWSER_VERSION) >= 8 || window.navigator.userAgent.indexOf("Trident/4.0") > -1) return;
|
|||
// var inputs = $('input').not(':input[type=button], :input[type=submit], :input[type=radio], :input[type=checkbox]');
|
|||
// inputs.each(function() {
|
|||
// var $input = $(this);
|
|||
// var axInput = $ax('#' + $input.attr('id'));
|
|||
// $input.css('height', (axInput.height() - 4 + 'px')).css('width', (axInput.width() - 2 + 'px'));
|
|||
// });
|
|||
|
|||
// var textAreas = $($ax.constants.TEXT_AREA_TYPE);
|
|||
// textAreas.each(function() {
|
|||
// var $textArea = $(this);
|
|||
// var axText = $ax('#' + $textArea.attr('id'));
|
|||
// $textArea.css('height', (axText.height() - 6 + 'px')).css('width', (axText.width() - 6 + 'px'));
|
|||
// });
|
|||
// };
|
|||
|
|||
// var _fixInputBackground = function() {
|
|||
// var inputs = $('input').not(':input[type=button], :input[type=submit], :input[type=radio], :input[type=checkbox]');
|
|||
// inputs = inputs.add($($ax.constants.TEXT_AREA_TYPE));
|
|||
// inputs.each(function() {
|
|||
// var $input = $(this);
|
|||
// if($input.css('background-color') == 'transparent') {
|
|||
// $input.css('background-image', 'url(../../transparent.gif)');
|
|||
// } else {
|
|||
// $input.css('background-image', '');
|
|||
// }
|
|||
// });
|
|||
// };
|
|||
|
|||
// $(document).ready(function() {
|
|||
// _fixIEStretchBackground();
|
|||
// _applyIEFixedPosition();
|
|||
// $axure.resize(function() {
|
|||
// _resizeIEBackground();
|
|||
// });
|
|||
// $ax.adaptive.bind('viewChanged', function() {
|
|||
// _fixIEStretchBackground();
|
|||
// _applyBackground();
|
|||
// _fixInputBackground();
|
|||
// });
|
|||
|
|||
|
|||
// _fixAllPngs();
|
|||
// _applyIERotation();
|
|||
// _applyBackground();
|
|||
// _fixInputSize();
|
|||
// _fixInputBackground();
|
|||
// });
|
|||
|
|||
|
|||
//});
|
@ -1,326 +0,0 @@ |
|||
$axure.internal(function($ax) { |
|||
|
|||
$(window.document).ready(function () { |
|||
|
|||
//var readyStart = (new Date()).getTime();
|
|||
|
|||
//this is because the page id is not formatted as a guid
|
|||
var pageId = $ax.pageData.page.packageId; |
|||
|
|||
var pageData = { |
|||
id: pageId, |
|||
pageName: $ax.pageData.page.name, |
|||
location: window.location.toString(), |
|||
notes: $ax.pageData.page.notes, |
|||
widgetNotes: $ax.pageData.page.annotations, |
|||
//clipToView: $ax.pageData.clipToView,
|
|||
defaultAdaptiveView: $ax.pageData.defaultAdaptiveView, |
|||
adaptiveViews: $ax.pageData.adaptiveViews, |
|||
masterNotes: [] |
|||
}; |
|||
|
|||
var fnPrefix = ''; |
|||
function pushNextPrefix() { |
|||
if (fnPrefix.length == 0) fnPrefix = 'A'; |
|||
else fnPrefix = fnPrefix[0] == 'Z' ? 'A'.repeat(fnPrefix.length + 1) : String.fromCharCode(fnPrefix.charCodeAt(0) + 1).repeat(fnPrefix.length); |
|||
} |
|||
|
|||
function populateNotes(pageForNotes) { |
|||
for (var master in pageForNotes.masters) { |
|||
//var master = pageForNotes.masters[i];
|
|||
var masterData = pageForNotes.masters[master]; |
|||
var hasWidgetNotes = masterData.annotations && masterData.annotations.length > 0; |
|||
if ((master.notes && !$.isEmptyObject(masterData.notes)) || hasWidgetNotes) { |
|||
if(hasWidgetNotes) pushNextPrefix(); |
|||
var m = {}; |
|||
m.pageName = masterData.name; |
|||
m.notes = masterData.notes; |
|||
m.widgetNotes = masterData.annotations; |
|||
pageData.masterNotes.push(m); |
|||
if(hasWidgetNotes) populateOwnerToFn(m.widgetNotes); |
|||
} |
|||
populateNotes(master); |
|||
} |
|||
} |
|||
|
|||
var ownerToFns = {}; |
|||
function populateOwnerToFn(widgetNotes) { |
|||
if(typeof widgetNotes == 'undefined') return false; |
|||
for (var i = 0; i < widgetNotes.length; i++) { |
|||
var widgetNote = widgetNotes[i]; |
|||
widgetNote['fn'] = fnPrefix + widgetNote['fn']; |
|||
var fn = widgetNote['fn']; |
|||
var ownerId = widgetNote['ownerId']; |
|||
if (ownerId !== undefined && ownerId.length > 0) { |
|||
var ownerLabels = ownerToFns[ownerId]; |
|||
if (ownerLabels == undefined) ownerLabels = []; |
|||
ownerLabels.push(fn); |
|||
ownerToFns[ownerId] = ownerLabels; |
|||
} |
|||
} |
|||
} |
|||
|
|||
populateOwnerToFn(pageData.widgetNotes); |
|||
populateNotes($ax.pageData); |
|||
pageData.ownerToFns = ownerToFns; |
|||
|
|||
$ax.pageData.notesData = pageData; |
|||
|
|||
//var anns = [];
|
|||
//$ax('*').each(function (dObj, elementId) {
|
|||
// pushAnnotation(dObj, elementId);
|
|||
//});
|
|||
|
|||
//function pushAnnotation(dObj, elementId) {
|
|||
// var ann = dObj.annotation;
|
|||
// if(ann) {
|
|||
// ann = $ax.deepCopy(ann);
|
|||
// ann["id"] = elementId;
|
|||
// ann["label"] = dObj.label + " (" + dObj.friendlyType + ")";
|
|||
// anns.push(ann);
|
|||
// }
|
|||
|
|||
// if(dObj.type === 'repeater' && dObj.objects) {
|
|||
// //if it's repeater, save the id as repeaterId@scriptId
|
|||
// for(var i = 0, len = dObj.objects.length; i < len; i++) {
|
|||
// var child = dObj.objects[i];
|
|||
// var scriptId = $ax.getScriptIdFromPath([child.id], elementId);
|
|||
// pushAnnotation(child, elementId + '@' + scriptId);
|
|||
// }
|
|||
// }
|
|||
//}
|
|||
|
|||
//pageData.widgetNotes = anns;
|
|||
|
|||
//only trigger the page.data setting if the window is on the mainframe
|
|||
var isMainFrame = false; |
|||
try { |
|||
if(window.name == 'mainFrame' || |
|||
(!CHROME_5_LOCAL && window.parent.$ && window.parent.$('#mainFrame').length > 0)) { |
|||
isMainFrame = true; |
|||
|
|||
$ax.messageCenter.addMessageListener(function(message, data) { |
|||
if(message == 'finishInit') { |
|||
_processTempInit(); |
|||
} |
|||
}); |
|||
|
|||
$axure.messageCenter.setState('page.data', pageData); |
|||
window.focus(); |
|||
} |
|||
} catch(e) { } |
|||
|
|||
//attach here for chrome local
|
|||
//$(window).on('load', function() {
|
|||
// $ax.style.initializeObjectTextAlignment($ax('*'));
|
|||
//});
|
|||
|
|||
if(!isMainFrame) _processTempInit(); |
|||
}); |
|||
|
|||
var touchCount = 0; |
|||
var lastTouch = Date.now(); |
|||
var _registerTouchCount = $ax.registerTouchCount = function (e) { |
|||
var now = Date.now(); |
|||
if (now - lastTouch < 375) { |
|||
if (++touchCount === 3) { |
|||
$(':input').blur(); |
|||
$ax.messageCenter.postMessage('tripleClick', true); |
|||
e.preventDefault(); |
|||
}; |
|||
} else { |
|||
touchCount = 1; |
|||
} |
|||
lastTouch = now; |
|||
}; |
|||
|
|||
// Block IOS stalling second tap.
|
|||
// Stop third click from also clicking mobile card
|
|||
var _clearTouchCount = $ax.clearTouchCount = function (e) { |
|||
if (touchCount === 3) { |
|||
touchCount = 0; |
|||
e.preventDefault(); |
|||
} |
|||
}; |
|||
|
|||
var _processTempInit = function() { |
|||
//var start = (new Date()).getTime();
|
|||
//var end = (new Date()).getTime();
|
|||
//window.alert('elapsed ' + (end - start));
|
|||
|
|||
$('iframe').each(function() { |
|||
var origSrc = $(this).attr('basesrc'); |
|||
|
|||
var $this = $(this); |
|||
if(origSrc) { |
|||
var newSrcUrl = origSrc.toLowerCase().indexOf('http://') == -1 ? $ax.globalVariableProvider.getLinkUrl(origSrc) : origSrc; |
|||
$this.attr('src', newSrcUrl); |
|||
} |
|||
|
|||
if(IOS) { |
|||
$this.parent().css('overflow', 'auto').css('-webkit-overflow-scrolling', 'touch').css('-ms-overflow-x', 'hidden').css('overflow-x', 'hidden'); |
|||
} |
|||
}); |
|||
|
|||
$axure.messageCenter.addMessageListener(function(message, data) { |
|||
if(message == 'setGlobalVar') { |
|||
$ax.globalVariableProvider.setVariableValue(data.globalVarName, data.globalVarValue, true); |
|||
} |
|||
}); |
|||
|
|||
window.lastFocusedClickable = null; |
|||
var _lastFocusedClickableSelector = 'input, a'; |
|||
var shouldOutline = true; |
|||
|
|||
$ax(function (dObj) { return dObj.tabbable; }).each(function (dObj, elementId) { |
|||
if ($ax.public.fn.IsLayer(dObj.type)) $ax.event.layerMapFocus(dObj, elementId); |
|||
var focusableId = $ax.event.getFocusableWidgetOrChildId(elementId); |
|||
var $focusable = $('#' + focusableId); |
|||
$focusable.attr("tabIndex", 0); |
|||
if($focusable.is('div') || $focusable.is('img')) { |
|||
$focusable.bind($ax.features.eventNames.mouseDownName, function() { |
|||
shouldOutline = false; |
|||
}); |
|||
attachFocusAndBlur($focusable); |
|||
} |
|||
}); |
|||
|
|||
$(window.document).bind($ax.features.eventNames.mouseUpName, function() { |
|||
shouldOutline = true; |
|||
}); |
|||
|
|||
attachFocusAndBlur($(_lastFocusedClickableSelector)); |
|||
|
|||
function attachFocusAndBlur($query) { |
|||
$query.focus(function () { |
|||
if(shouldOutline) { |
|||
$(this).css('outline', ''); |
|||
} else { |
|||
$(this).css('outline', 'none'); |
|||
} |
|||
window.lastFocusedClickable = this; |
|||
}).blur(function () { |
|||
if(window.lastFocusedClickable == this) window.lastFocusedClickable = null; |
|||
}); |
|||
} |
|||
|
|||
$(window.document).bind('keyup', function (e) { |
|||
switch(e.which) { |
|||
case 13: |
|||
case 32: |
|||
if(window.lastFocusedClickable) $(window.lastFocusedClickable).click(); |
|||
break; |
|||
default: return; // exit this handler for other keys
|
|||
} |
|||
}); |
|||
|
|||
//if($ax.document.configuration.hideAddress) {
|
|||
// $(window).on('load', function() {
|
|||
// window.setTimeout(function() {
|
|||
// window.scrollTo(0, 0.9);
|
|||
// }, 0);
|
|||
// });
|
|||
//}
|
|||
|
|||
//if($ax.document.configuration.preventScroll) {
|
|||
// $(window.document).bind('touchmove', function(e) {
|
|||
// var inScrollable = $ax.legacy.GetScrollable(e.target) != window.document.body;
|
|||
// if(!inScrollable) {
|
|||
// e.preventDefault();
|
|||
// }
|
|||
// });
|
|||
|
|||
// $ax(function(diagramObject) {
|
|||
// return $ax.public.fn.IsDynamicPanel(diagramObject.type) && diagramObject.scrollbars != 'none';
|
|||
// }).$().children().bind('touchstart', function() {
|
|||
// var target = this;
|
|||
// var top = target.scrollTop;
|
|||
// if(top <= 0) target.scrollTop = 1;
|
|||
// if(top + target.offsetHeight >= target.scrollHeight) target.scrollTop = target.scrollHeight - target.offsetHeight - 1;
|
|||
// });
|
|||
//}
|
|||
|
|||
if(OS_MAC && WEBKIT) { |
|||
$ax(function(diagramObject) { |
|||
return $ax.public.fn.IsComboBox(diagramObject.type); |
|||
}).each(function(obj, id) { |
|||
$jobj($ax.INPUT(id)).css('-webkit-appearance', 'menulist-button'); |
|||
}); |
|||
} |
|||
|
|||
if($ax.features.supports.mobile) { |
|||
$('html').first().on('touchstart', _registerTouchCount); |
|||
$('html').first().on('touchend', _clearTouchCount); |
|||
|
|||
// Stop pinch zoom (stopping all gestures for now)
|
|||
// Gesturestart is only supported in Safari
|
|||
if (SAFARI) { |
|||
document.addEventListener("gesturestart", function (e) { |
|||
e.preventDefault(); |
|||
}); |
|||
} |
|||
} |
|||
|
|||
$ax.annotation.initialize(); |
|||
|
|||
$ax.legacy.BringFixedToFront(); |
|||
$ax.event.initialize(); |
|||
$ax.style.initialize(); |
|||
$ax.visibility.initialize(); |
|||
$ax.repeater.initialize(); |
|||
$ax.dynamicPanelManager.initialize(); //needs to be called after visibility is initialized
|
|||
$ax.adaptive.initialize(); |
|||
$ax.loadDynamicPanelsAndMasters(); |
|||
$ax.adaptive.loadFinished(); |
|||
var start = (new Date()).getTime(); |
|||
$ax.repeater.initRefresh(); |
|||
var end = (new Date()).getTime(); |
|||
console.log('loadTime: ' + (end - start) / 1000); |
|||
$ax.style.prefetch(); |
|||
|
|||
$(window).resize(); |
|||
|
|||
//var readyEnd = (new Date()).getTime();
|
|||
//window.alert('elapsed ' + (readyEnd - readyStart));
|
|||
}; |
|||
}); |
|||
|
|||
/* extend canvas */ |
|||
var gv_hasCanvas = false; |
|||
(function() { |
|||
var _canvas = document.createElement('canvas'), proto, abbrev; |
|||
if(gv_hasCanvas = !!(_canvas.getContext && _canvas.getContext('2d')) && typeof (CanvasGradient) !== 'undefined') { |
|||
function chain(func) { |
|||
return function() { |
|||
return func.apply(this, arguments) || this; |
|||
}; |
|||
} |
|||
|
|||
with(proto = CanvasRenderingContext2D.prototype) for(var func in abbrev = { |
|||
a: arc, |
|||
b: beginPath, |
|||
n: clearRect, |
|||
c: clip, |
|||
p: closePath, |
|||
g: createLinearGradient, |
|||
f: fill, |
|||
j: fillRect, |
|||
z: function(s) { this.fillStyle = s; }, |
|||
l: lineTo, |
|||
w: function(w) { this.lineWidth = w; }, |
|||
m: moveTo, |
|||
q: quadraticCurveTo, |
|||
h: rect, |
|||
r: restore, |
|||
o: rotate, |
|||
s: save, |
|||
x: scale, |
|||
y: function(s) { this.strokeStyle = s; }, |
|||
u: setTransform, |
|||
k: stroke, |
|||
i: strokeRect, |
|||
t: translate |
|||
}) proto[func] = chain(abbrev[func]); |
|||
CanvasGradient.prototype.a = chain(CanvasGradient.prototype.addColorStop); |
|||
} |
|||
})(); |
@ -1,91 +0,0 @@ |
|||
$axure.internal(function ($ax) { |
|||
if ((IOS && SAFARI) || SHARE_APP) { |
|||
var outerHtml = document.documentElement; |
|||
outerHtml.id = 'ios-safari'; |
|||
var html = document.createElement('html'); |
|||
html.id = 'ios-safari-html'; |
|||
outerHtml.appendChild(html); |
|||
var body = document.body; |
|||
html.appendChild(body); |
|||
Object.defineProperty(document, 'body', { |
|||
get: function () { |
|||
return body; |
|||
} |
|||
}); |
|||
var fixedBody = document.createElement('body'); |
|||
fixedBody.id = 'ios-safari-fixed'; |
|||
outerHtml.appendChild(fixedBody); |
|||
var fixedBase = document.createElement('div'); |
|||
fixedBase.id = 'base-fixed'; |
|||
fixedBody.appendChild(fixedBase); |
|||
|
|||
var isDevice = false; |
|||
var deviceWidth = 0; |
|||
var updateHtmlWidth = function (panelWidthOffset, scale, height, scaleN) { |
|||
var iosSafHtml = $('#ios-safari-html'); |
|||
iosSafHtml.css('overflow', ''); |
|||
iosSafHtml.css('overflow-x', ''); |
|||
iosSafHtml.css('height', ''); |
|||
if (isDevice) { |
|||
iosSafHtml.width(deviceWidth / scaleN); |
|||
iosSafHtml.css('overflow-x', 'hidden'); |
|||
} else { |
|||
var isLandscape = window.orientation != 0 && window.orientation != 180; |
|||
var mobileWidth = isLandscape ? window.screen.height : window.screen.width |
|||
iosSafHtml.width((mobileWidth - panelWidthOffset) / scaleN); |
|||
} |
|||
if (scale == 1) { |
|||
iosSafHtml.css('overflow-x', 'hidden'); |
|||
iosSafHtml.css('height', (height / scaleN) + 'px'); |
|||
} else if (scale == 2) iosSafHtml.css('overflow', 'hidden'); |
|||
}; |
|||
|
|||
updateHtmlWidth(0); |
|||
|
|||
$axure('*').each(function (obj, element) { |
|||
if (obj && obj.fixedVertical && obj.fixedKeepInFront) { |
|||
var parent = $axure('#' + element).getParents(false, ['item', 'state'])[0]; |
|||
if (!parent) { |
|||
$('#base-fixed').append($('#' + element)); |
|||
} |
|||
} |
|||
}); |
|||
|
|||
$axure.messageCenter.addMessageListener(function (message, data) { |
|||
if (message == "setContentScale") { |
|||
updateHtmlWidth(data.panelWidthOffset, data.scale, data.viewportHeight, data.scaleN); |
|||
} else if (message == "setDeviceMode") { |
|||
isDevice = data.device && !data.scaleToWidth; |
|||
if (isDevice) deviceWidth = data.width; |
|||
updateHtmlWidth(0); |
|||
} |
|||
}); |
|||
|
|||
|
|||
$('#ios-safari-html').scroll(function () { |
|||
$axure.updateWindowInfo(); |
|||
}); |
|||
|
|||
var scrollStartY; |
|||
var maxScrollY |
|||
var touchStart; |
|||
$axure('*').each(function (obj, element) { |
|||
if (obj && obj.scrollbars && obj.scrollbars.toLowerCase() != 'none') { |
|||
if (obj.scrollbars == 'horizontalAsNeeded') return; |
|||
|
|||
$('#' + element).on('touchstart', function (e) { |
|||
touchStart = e.pageY; |
|||
var stateId = $ax.visibility.GetPanelState($('#' + element).attr('id')); |
|||
scrollStartY = $('#' + stateId).scrollTop(); |
|||
maxScrollY = $('#' + stateId)[0].scrollHeight - $('#' + stateId).height(); |
|||
}); |
|||
|
|||
$('#' + element).on('touchmove', function (e) { |
|||
if (maxScrollY <= 0) return false; |
|||
if (scrollStartY == 0 && e.pageY > touchStart) e.preventDefault(); |
|||
if (scrollStartY == maxScrollY && e.pageY < touchStart) e.preventDefault(); |
|||
}); |
|||
} |
|||
}); |
|||
} |
|||
}); |
@ -1,166 +0,0 @@ |
|||
//stored on each browser event
|
|||
var windowEvent; |
|||
|
|||
$axure.internal(function($ax) { |
|||
var _legacy = {}; |
|||
$ax.legacy = _legacy; |
|||
|
|||
var Forms = window.document.getElementsByTagName("FORM"); |
|||
for(var i = 0; i < Forms.length; i++) { |
|||
var Form = Forms[i]; |
|||
Form.onclick = $ax.legacy.SuppressBubble; |
|||
} |
|||
|
|||
$ax.legacy.SuppressBubble = function(event) { |
|||
if(IE_10_AND_BELOW) { |
|||
window.event.cancelBubble = true; |
|||
window.event.returnValue = false; |
|||
} else { |
|||
if(event) { |
|||
event.stopPropagation(); |
|||
} |
|||
} |
|||
}; |
|||
|
|||
$ax.legacy.BringToFront = function(id, skipFixed) { |
|||
_bringToFrontHelper(id); |
|||
if(!skipFixed) $ax.legacy.BringFixedToFront(); |
|||
}; |
|||
|
|||
var _bringToFrontHelper = function(id) { |
|||
var target = window.document.getElementById(id); |
|||
if(target == null) return; |
|||
$ax.globals.MaxZIndex = $ax.globals.MaxZIndex + 1; |
|||
target.style.zIndex = $ax.globals.MaxZIndex; |
|||
}; |
|||
|
|||
$ax.legacy.BringFixedToFront = function() { |
|||
$ax(function(diagramObject) { return diagramObject.fixedKeepInFront; }).each(function(diagramObject, scriptId) { |
|||
_bringToFrontHelper(scriptId); |
|||
}); |
|||
}; |
|||
|
|||
$ax.legacy.SendToBack = function(id) { |
|||
var target = window.document.getElementById(id); |
|||
if(target == null) return; |
|||
target.style.zIndex = $ax.globals.MinZIndex = $ax.globals.MinZIndex - 1; |
|||
}; |
|||
|
|||
$ax.legacy.RefreshScreen = function() { |
|||
var oldColor = window.document.body.style.backgroundColor; |
|||
var setColor = (oldColor == "rgb(0,0,0)") ? "#FFFFFF" : "#000000"; |
|||
window.document.body.style.backgroundColor = setColor; |
|||
window.document.body.style.backgroundColor = oldColor; |
|||
}; |
|||
|
|||
$ax.legacy.getAbsoluteLeft = function(currentNode, elementId) { |
|||
var oldDisplay = currentNode.css('display'); |
|||
var displaySet = false; |
|||
if(oldDisplay == 'none') { |
|||
currentNode.css('display', ''); |
|||
displaySet = true; |
|||
} |
|||
var left = currentNode.offset().left; |
|||
|
|||
// Special Layer code
|
|||
if($ax.getTypeFromElementId(elementId) == 'layer') { |
|||
var first = true; |
|||
var children = currentNode.children(); |
|||
for(var i = 0; i < children.length; i++) { |
|||
var child = $(children[i]); |
|||
var subDisplaySet = false; |
|||
if(child.css('display') == 'none') { |
|||
child.css('display', ''); |
|||
subDisplaySet = true; |
|||
} |
|||
if(first) left = child.offset().left; |
|||
else left = Math.min(child.offset().left, left); |
|||
first = false; |
|||
|
|||
if(subDisplaySet) child.css('display', 'none'); |
|||
} |
|||
} |
|||
|
|||
if (displaySet) currentNode.css('display', oldDisplay); |
|||
|
|||
return $axure.fn.bodyToWorld(left, true); |
|||
}; |
|||
|
|||
$ax.legacy.getAbsoluteTop = function(currentNode, elementId) { |
|||
var oldDisplay = currentNode.css('display'); |
|||
var displaySet = false; |
|||
if(oldDisplay == 'none') { |
|||
currentNode.css('display', ''); |
|||
displaySet = true; |
|||
} |
|||
var top = currentNode.offset().top; |
|||
|
|||
// Special Layer code
|
|||
if ($ax.getTypeFromElementId(elementId) == 'layer') { |
|||
var first = true; |
|||
var children = currentNode.children(); |
|||
for (var i = 0; i < children.length; i++) { |
|||
var child = $(children[i]); |
|||
var subDisplaySet = false; |
|||
if (child.css('display') == 'none') { |
|||
child.css('display', ''); |
|||
subDisplaySet = true; |
|||
} |
|||
if (first) top = child.offset().top; |
|||
else top = Math.min(child.offset().top, top); |
|||
first = false; |
|||
|
|||
if (subDisplaySet) child.css('display', 'none'); |
|||
} |
|||
} |
|||
|
|||
if(displaySet) currentNode.css('display', oldDisplay); |
|||
return top; |
|||
}; |
|||
|
|||
// ****************** Annotation and Link Functions ****************** //
|
|||
|
|||
$ax.legacy.GetAnnotationHtml = function(annJson) { |
|||
var retVal = ""; |
|||
for(var noteName in annJson) { |
|||
if(noteName != "label" && noteName != "id") { |
|||
retVal += "<div class='annotationName'>" + noteName + "</div>"; |
|||
retVal += "<div class='annotationValue'>" + linkify(annJson[noteName]) + "</div>"; |
|||
} |
|||
} |
|||
return retVal; |
|||
|
|||
function linkify(text) { |
|||
var urlRegex = /(\b(((https?|ftp|file):\/\/)|(www\.))[-A-Z0-9+&@#\/%?=~_|!:,.;]*[-A-Z0-9+&@#\/%=~_|])/ig; |
|||
return text.replace(urlRegex, function (url, b, c) { |
|||
var url2 = (c == 'www.') ? 'http://' + url : url; |
|||
return '<a href="' + url2 + '" target="_blank" class="noteLink">' + url + '</a>'; |
|||
}); |
|||
} |
|||
}; |
|||
|
|||
|
|||
$ax.legacy.GetScrollable = function(target) { |
|||
var $target = $(target); |
|||
var last = $target; |
|||
// Start past inital target. Can't scroll to target in itself, must be some ancestor.
|
|||
var current = last.parent(); |
|||
|
|||
while(!current.is('body') && !current.is('html')) { |
|||
var elementId = current.attr('id'); |
|||
var diagramObject = elementId && $ax.getObjectFromElementId(elementId); |
|||
if (diagramObject && $ax.public.fn.IsDynamicPanel(diagramObject.type) && diagramObject.scrollbars != 'none') { |
|||
//returns the panel diagram div which handles scrolling
|
|||
return $ax.dynamicPanelManager.getShownState(current.attr('id'))[0]; |
|||
} |
|||
last = current; |
|||
current = current.parent(); |
|||
} |
|||
// Need to do this because of ie
|
|||
if(IE_10_AND_BELOW) return window.document.documentElement; |
|||
else return window.document.body; |
|||
}; |
|||
|
|||
|
|||
|
|||
}); |
@ -1,554 +0,0 @@ |
|||
$axure.internal(function($ax) { |
|||
$ax.public.fn.matrixMultiply = function(matrix, vector) { |
|||
if(!matrix.tx) matrix.tx = 0; |
|||
if(!matrix.ty) matrix.ty = 0; |
|||
var outX = matrix.m11 * vector.x + matrix.m12 * vector.y + matrix.tx; |
|||
var outY = matrix.m21 * vector.x + matrix.m22 * vector.y + matrix.ty; |
|||
return { x: outX, y: outY }; |
|||
} |
|||
|
|||
$ax.public.fn.matrixInverse = function(matrix) { |
|||
if(!matrix.tx) matrix.tx = 0; |
|||
if(!matrix.ty) matrix.ty = 0; |
|||
|
|||
var determinant = matrix.m11*matrix.m22 - matrix.m12*matrix.m21; |
|||
//var threshold = (M11 * M11 + M22 *M22 + M12 *M12+ M21 *M21) / 100000;
|
|||
//if(determinant.DeltaEquals(0, threshold) && determinant < 0.01) {
|
|||
// return Invalid;
|
|||
//}
|
|||
return { |
|||
m11 : matrix.m22/determinant, |
|||
m12 : -matrix.m12/determinant, |
|||
tx : (matrix.ty*matrix.m12 - matrix.tx*matrix.m22)/determinant, |
|||
m21: -matrix.m21 / determinant, |
|||
m22: matrix.m11 / determinant, |
|||
ty: (matrix.tx * matrix.m21 - matrix.ty * matrix.m11) / determinant |
|||
}; |
|||
} |
|||
|
|||
|
|||
$ax.public.fn.matrixMultiplyMatrix = function (matrix1, matrix2) { |
|||
if (!matrix1.tx) matrix1.tx = 0; |
|||
if (!matrix1.ty) matrix1.ty = 0; |
|||
if (!matrix2.tx) matrix2.tx = 0; |
|||
if (!matrix2.ty) matrix2.ty = 0; |
|||
|
|||
return { |
|||
m11: matrix1.m12*matrix2.m21 + matrix1.m11*matrix2.m11, |
|||
m12: matrix1.m12*matrix2.m22 + matrix1.m11*matrix2.m12, |
|||
tx: matrix1.m12 * matrix2.ty + matrix1.m11 * matrix2.tx + matrix1.tx, |
|||
m21: matrix1.m22 * matrix2.m21 + matrix1.m21 * matrix2.m11, |
|||
m22: matrix1.m22 * matrix2.m22 + matrix1.m21 * matrix2.m12, |
|||
ty: matrix1.m22 * matrix2.ty + matrix1.m21 * matrix2.tx + matrix1.ty, |
|||
}; |
|||
} |
|||
|
|||
|
|||
$ax.public.fn.transformFromElement = function (element) { |
|||
var st = window.getComputedStyle(element, null); |
|||
|
|||
var tr = st.getPropertyValue("-webkit-transform") || |
|||
st.getPropertyValue("-moz-transform") || |
|||
st.getPropertyValue("-ms-transform") || |
|||
st.getPropertyValue("-o-transform") || |
|||
st.getPropertyValue("transform"); |
|||
|
|||
if (tr.indexOf('none') < 0) { |
|||
var matrix = tr.split('(')[1]; |
|||
matrix = matrix.split(')')[0]; |
|||
matrix = matrix.split(','); |
|||
for (var l = 0; l < matrix.length; l++) { |
|||
matrix[l] = Number(matrix[l]); |
|||
} |
|||
|
|||
} else { matrix = [1.0, 0.0, 0.0, 1.0, 0.0, 0.0]; } |
|||
|
|||
return matrix; |
|||
// matrix[0] = cosine, matrix[1] = sine.
|
|||
// Assuming the element is still orthogonal.
|
|||
} |
|||
|
|||
$ax.public.fn.vectorMinus = function(vector1, vector2) { return { x: vector1.x - vector2.x, y: vector1.y - vector2.y }; } |
|||
|
|||
$ax.public.fn.vectorPlus = function (vector1, vector2) { return { x: vector1.x + vector2.x, y: vector1.y + vector2.y }; } |
|||
|
|||
$ax.public.fn.vectorMidpoint = function (vector1, vector2) { return { x: (vector1.x + vector2.x) / 2.0, y: (vector1.y + vector2.y) / 2.0 }; } |
|||
|
|||
$ax.public.fn.fourCornersToBasis = function (fourCorners) { |
|||
return { |
|||
widthVector: $ax.public.fn.vectorMinus(fourCorners.widgetTopRight, fourCorners.widgetTopLeft), |
|||
heightVector: $ax.public.fn.vectorMinus(fourCorners.widgetBottomLeft, fourCorners.widgetTopLeft) |
|||
}; |
|||
} |
|||
|
|||
$ax.public.fn.matrixString = function(m11, m21, m12, m22, tx, ty) { |
|||
return "Matrix(" + m11 + "," + m21 + "," + m12 + "," + m22 + ", " + tx + ", " + ty + ")"; |
|||
} |
|||
|
|||
//$ax.public.fn.getWidgetBoundingRect = function (widgetId) {
|
|||
// var emptyRect = { left: 0, top: 0, centerPoint: { x: 0, y: 0 }, width: 0, height: 0 };
|
|||
// var element = document.getElementById(widgetId);
|
|||
// if (!element) return emptyRect;
|
|||
|
|||
// var object = $obj(widgetId);
|
|||
// if (object && object.type && $ax.public.fn.IsLayer(object.type)) {
|
|||
// var layerChildren = _getLayerChildrenDeep(widgetId);
|
|||
// if (!layerChildren) return emptyRect;
|
|||
// else return _getBoundingRectForMultipleWidgets(layerChildren);
|
|||
// }
|
|||
// return _getBoundingRectForSingleWidget(widgetId);
|
|||
//};
|
|||
|
|||
var _getLayerChildrenDeep = $ax.public.fn.getLayerChildrenDeep = function (layerId, includeLayers, includeHidden) { |
|||
var deep = []; |
|||
var children = $ax('#' + layerId).getChildren()[0].children; |
|||
for (var index = 0; index < children.length; index++) { |
|||
var childId = children[index]; |
|||
if(!includeHidden && !$ax.visibility.IsIdVisible(childId)) continue; |
|||
if ($ax.public.fn.IsLayer($obj(childId).type)) { |
|||
if (includeLayers) deep.push(childId); |
|||
var recursiveChildren = _getLayerChildrenDeep(childId, includeLayers, includeHidden); |
|||
for (var j = 0; j < recursiveChildren.length; j++) deep.push(recursiveChildren[j]); |
|||
} else deep.push(childId); |
|||
} |
|||
return deep; |
|||
}; |
|||
|
|||
//var _getBoundingRectForMultipleWidgets = function (widgetsIdArray, relativeToPage) {
|
|||
// if (!widgetsIdArray || widgetsIdArray.constructor !== Array) return undefined;
|
|||
// if (widgetsIdArray.length == 0) return { left: 0, top: 0, centerPoint: { x: 0, y: 0 }, width: 0, height: 0 };
|
|||
// var widgetRect = _getBoundingRectForSingleWidget(widgetsIdArray[0], relativeToPage, true);
|
|||
// var boundingRect = { left: widgetRect.left, right: widgetRect.right, top: widgetRect.top, bottom: widgetRect.bottom };
|
|||
|
|||
// for (var index = 1; index < widgetsIdArray.length; index++) {
|
|||
// widgetRect = _getBoundingRectForSingleWidget(widgetsIdArray[index], relativeToPage);
|
|||
// boundingRect.left = Math.min(boundingRect.left, widgetRect.left);
|
|||
// boundingRect.top = Math.min(boundingRect.top, widgetRect.top);
|
|||
// boundingRect.right = Math.max(boundingRect.right, widgetRect.right);
|
|||
// boundingRect.bottom = Math.max(boundingRect.bottom, widgetRect.bottom);
|
|||
// }
|
|||
|
|||
// boundingRect.centerPoint = { x: (boundingRect.right + boundingRect.left) / 2.0, y: (boundingRect.bottom + boundingRect.top) / 2.0 };
|
|||
// boundingRect.width = boundingRect.right - boundingRect.left;
|
|||
// boundingRect.height = boundingRect.bottom - boundingRect.top;
|
|||
// return boundingRect;
|
|||
//};
|
|||
|
|||
//var _getBoundingRectForSingleWidget = function (widgetId, relativeToPage, justSides) {
|
|||
// var element = document.getElementById(widgetId);
|
|||
// var boundingRect, tempBoundingRect, position;
|
|||
// var displayChanged = _displayHackStart(element);
|
|||
|
|||
// if (_isCompoundVectorHtml(element)) {
|
|||
// //tempBoundingRect = _getCompoundImageBoundingClientSize(widgetId);
|
|||
// //position = { left: tempBoundingRect.left, top: tempBoundingRect.top };
|
|||
// position = $(element).position();
|
|||
// tempBoundingRect = {};
|
|||
// tempBoundingRect.left = position.left; //= _getCompoundImageBoundingClientSize(widgetId);
|
|||
// tempBoundingRect.top = position.top;
|
|||
// tempBoundingRect.width = Number(element.getAttribute('data-width'));
|
|||
// tempBoundingRect.height = Number(element.getAttribute('data-height'));
|
|||
// } else {
|
|||
// var boundingElement = element;
|
|||
// if($ax.dynamicPanelManager.isIdFitToContent(widgetId)) {
|
|||
// var stateId = $ax.visibility.GetPanelState(widgetId);
|
|||
// if(stateId != '') boundingElement = document.getElementById(stateId);
|
|||
// }
|
|||
// tempBoundingRect = boundingElement.getBoundingClientRect();
|
|||
|
|||
// var jElement = $(element);
|
|||
// position = jElement.position();
|
|||
// if(jElement.css('position') == 'fixed') {
|
|||
// position.left += Number(jElement.css('margin-left').replace("px", ""));
|
|||
// position.top += Number(jElement.css('margin-top').replace("px", ""));
|
|||
// }
|
|||
// }
|
|||
|
|||
// var layers = $ax('#' + widgetId).getParents(true, ['layer'])[0];
|
|||
// var flip = '';
|
|||
// var mirrorWidth = 0;
|
|||
// var mirrorHeight = 0;
|
|||
// for (var i = 0; i < layers.length; i++) {
|
|||
|
|||
// //should always be 0,0
|
|||
// var layerPos = $jobj(layers[i]).position();
|
|||
// position.left += layerPos.left;
|
|||
// position.top += layerPos.top;
|
|||
|
|||
// var outer = $ax.visibility.applyWidgetContainer(layers[i], true, true);
|
|||
// if (outer.length) {
|
|||
// var outerPos = outer.position();
|
|||
// position.left += outerPos.left;
|
|||
// position.top += outerPos.top;
|
|||
// }
|
|||
|
|||
// //when a group is flipped we find the unflipped position
|
|||
// var inner = $jobj(layers[i] + '_container_inner');
|
|||
// var taggedFlip = inner.data('flip');
|
|||
// if (inner.length && taggedFlip) {
|
|||
// //only account for flip if transform is applied
|
|||
// var matrix = taggedFlip && (inner.css("-webkit-transform") || inner.css("-moz-transform") ||
|
|||
// inner.css("-ms-transform") || inner.css("-o-transform") || inner.css("transform"));
|
|||
// if (matrix !== 'none') {
|
|||
// flip = taggedFlip;
|
|||
// mirrorWidth = $ax.getNumFromPx(inner.css('width'));
|
|||
// mirrorHeight = $ax.getNumFromPx(inner.css('height'));
|
|||
// }
|
|||
// }
|
|||
// }
|
|||
// //Now account for flip
|
|||
// if (flip == 'x') position.top = mirrorHeight - position.top - element.getBoundingClientRect().height;
|
|||
// else if (flip == 'y') position.left = mirrorWidth - position.left - element.getBoundingClientRect().width;
|
|||
|
|||
// boundingRect = {
|
|||
// left: position.left,
|
|||
// right: position.left + tempBoundingRect.width,
|
|||
// top: position.top,
|
|||
// bottom: position.top + tempBoundingRect.height
|
|||
// };
|
|||
|
|||
// _displayHackEnd(displayChanged);
|
|||
// if (justSides) return boundingRect;
|
|||
|
|||
// boundingRect.width = boundingRect.right - boundingRect.left;
|
|||
// boundingRect.height = boundingRect.bottom - boundingRect.top;
|
|||
|
|||
// boundingRect.centerPoint = {
|
|||
// x: boundingRect.width / 2 + boundingRect.left,
|
|||
// y: boundingRect.height / 2 + boundingRect.top
|
|||
// };
|
|||
|
|||
// return boundingRect;
|
|||
//};
|
|||
|
|||
var _getPointAfterRotate = $ax.public.fn.getPointAfterRotate = function (angleInDegrees, pointToRotate, centerPoint) { |
|||
var displacement = $ax.public.fn.vectorMinus(pointToRotate, centerPoint); |
|||
var rotationMatrix = $ax.public.fn.rotationMatrix(angleInDegrees); |
|||
rotationMatrix.tx = centerPoint.x; |
|||
rotationMatrix.ty = centerPoint.y; |
|||
return $ax.public.fn.matrixMultiply(rotationMatrix, displacement); |
|||
}; |
|||
|
|||
$ax.public.fn.getBoundingSizeForRotate = function(width, height, rotation) { |
|||
// point to rotate around doesn't matter since we just care about size, if location matter we need more args and location matters.
|
|||
|
|||
var origin = { x: 0, y: 0 }; |
|||
|
|||
var corner1 = { x: width, y: 0 }; |
|||
var corner2 = { x: 0, y: height }; |
|||
var corner3 = { x: width, y: height }; |
|||
|
|||
corner1 = _getPointAfterRotate(rotation, corner1, origin); |
|||
corner2 = _getPointAfterRotate(rotation, corner2, origin); |
|||
corner3 = _getPointAfterRotate(rotation, corner3, origin); |
|||
|
|||
var left = Math.min(0, corner1.x, corner2.x, corner3.x); |
|||
var right = Math.max(0, corner1.x, corner2.x, corner3.x); |
|||
var top = Math.min(0, corner1.y, corner2.y, corner3.y); |
|||
var bottom = Math.max(0, corner1.y, corner2.y, corner3.y); |
|||
|
|||
return { width: right - left, height: bottom - top }; |
|||
} |
|||
|
|||
$ax.public.fn.getBoundingRectForRotate = function (boundingRect, rotation) { |
|||
var centerPoint = boundingRect.centerPoint; |
|||
var corner1 = { x: boundingRect.left, y: boundingRect.top }; |
|||
var corner2 = { x: boundingRect.right, y: boundingRect.top }; |
|||
var corner3 = { x: boundingRect.right, y: boundingRect.bottom }; |
|||
var corner4 = { x: boundingRect.left, y: boundingRect.bottom }; |
|||
corner1 = _getPointAfterRotate(rotation, corner1, centerPoint); |
|||
corner2 = _getPointAfterRotate(rotation, corner2, centerPoint); |
|||
corner3 = _getPointAfterRotate(rotation, corner3, centerPoint); |
|||
corner4 = _getPointAfterRotate(rotation, corner4, centerPoint); |
|||
|
|||
var left = Math.min(corner1.x, corner2.x, corner3.x, corner4.x); |
|||
var right = Math.max(corner1.x, corner2.x, corner3.x, corner4.x); |
|||
var top = Math.min(corner1.y, corner2.y, corner3.y, corner4.y); |
|||
var bottom = Math.max(corner1.y, corner2.y, corner3.y, corner4.y); |
|||
|
|||
return { left: left, top: top, width: right - left, height: bottom - top }; |
|||
} |
|||
|
|||
|
|||
//$ax.public.fn.getPositionRelativeToParent = function (elementId) {
|
|||
// var element = document.getElementById(elementId);
|
|||
// var list = _displayHackStart(element);
|
|||
// var position = $(element).position();
|
|||
// _displayHackEnd(list);
|
|||
// return position;
|
|||
//};
|
|||
|
|||
//var _displayHackStart = $ax.public.fn.displayHackStart = function (element) {
|
|||
// // TODO: Options: 1) stop setting display none. Big change for this late in the game. 2) Implement our own bounding.
|
|||
// // TODO: 3) Current method is look for any parents that are set to none, and and temporarily unblock. Don't like it, but it works.
|
|||
// var parent = element;
|
|||
// var displays = [];
|
|||
// while (parent) {
|
|||
// if (parent.style.display == 'none') {
|
|||
// displays.push(parent);
|
|||
// //use block to overwrites default hidden objects' display
|
|||
// parent.style.display = 'block';
|
|||
// }
|
|||
// parent = parent.parentElement;
|
|||
// }
|
|||
|
|||
// return displays;
|
|||
//};
|
|||
|
|||
//var _displayHackEnd = $ax.public.fn.displayHackEnd = function (displayChangedList) {
|
|||
// for (var i = 0; i < displayChangedList.length; i++) displayChangedList[i].style.display = 'none';
|
|||
//};
|
|||
|
|||
|
|||
var _isCompoundVectorHtml = $ax.public.fn.isCompoundVectorHtml = function(hElement) { |
|||
return hElement.hasAttribute('compoundmode') && hElement.getAttribute('compoundmode') == "true"; |
|||
} |
|||
|
|||
$ax.public.fn.removeCompound = function (jobj) { if(_isCompoundVectorHtml(jobj[0])) jobj.removeClass('compound'); } |
|||
$ax.public.fn.restoreCompound = function (jobj) { if (_isCompoundVectorHtml(jobj[0])) jobj.addClass('compound'); } |
|||
|
|||
$ax.public.fn.compoundIdFromComponent = function(id) { |
|||
|
|||
var pPos = id.indexOf('p'); |
|||
var dashPos = id.indexOf('-'); |
|||
if (pPos < 1) return id; |
|||
else if (dashPos < 0) return id.substring(0, pPos); |
|||
else return id.substring(0, pPos) + id.substring(dashPos); |
|||
} |
|||
|
|||
$ax.public.fn.l2 = function (x, y) { return Math.sqrt(x * x + y * y); } |
|||
|
|||
$ax.public.fn.convertToSingleImage = function (jobj) { |
|||
if(!jobj[0]) return; |
|||
|
|||
var widgetId = jobj[0].id; |
|||
var object = $obj(widgetId); |
|||
|
|||
if ($ax.public.fn.IsLayer(object.type)) { |
|||
var recursiveChildren = _getLayerChildrenDeep(widgetId, true); |
|||
for (var j = 0; j < recursiveChildren.length; j++) |
|||
$ax.public.fn.convertToSingleImage($jobj(recursiveChildren[j])); |
|||
return; |
|||
} |
|||
|
|||
//var layer =
|
|||
|
|||
if(!_isCompoundVectorHtml(jobj[0])) return; |
|||
|
|||
|
|||
$('#' + widgetId).removeClass("compound"); |
|||
$('#' + widgetId + '_img').removeClass("singleImg"); |
|||
jobj[0].setAttribute('compoundmode', 'false'); |
|||
|
|||
var components = object.compoundChildren; |
|||
delete object.generateCompound; |
|||
for (var i = 0; i < components.length; i++) { |
|||
var componentJobj = $jobj($ax.public.fn.getComponentId(widgetId, components[i])); |
|||
componentJobj.css('display', 'none'); |
|||
componentJobj.css('visibility', 'hidden'); |
|||
} |
|||
} |
|||
|
|||
|
|||
$ax.public.fn.getContainerDimensions = function(query) { |
|||
// returns undefined if no containers found.
|
|||
var containerDimensions; |
|||
for (var i = 0; i < query[0].children.length; i++) { |
|||
var node = query[0].children[i]; |
|||
if (node.id.indexOf(query[0].id) >= 0 && node.id.indexOf('container') >= 0) { |
|||
containerDimensions = node.style; |
|||
} |
|||
} |
|||
return containerDimensions; |
|||
} |
|||
|
|||
|
|||
$ax.public.fn.rotationMatrix = function (angleInDegrees) { |
|||
var angleInRadians = angleInDegrees * (Math.PI / 180); |
|||
var cosTheta = Math.cos(angleInRadians); |
|||
var sinTheta = Math.sin(angleInRadians); |
|||
|
|||
return { m11: cosTheta, m12: -sinTheta, m21: sinTheta, m22: cosTheta, tx: 0.0, ty: 0.0 }; |
|||
} |
|||
|
|||
$ax.public.fn.GetFieldFromStyle = function (query, field) { |
|||
var raw = query[0].style[field]; |
|||
if (!raw) raw = query.css(field); |
|||
return Number(raw.replace('px', '')); |
|||
} |
|||
|
|||
|
|||
$ax.public.fn.setTransformHowever = function (transformString) { |
|||
return { |
|||
'-webkit-transform': transformString, |
|||
'-moz-transform': transformString, |
|||
'-ms-transform': transformString, |
|||
'-o-transform': transformString, |
|||
'transform': transformString |
|||
}; |
|||
} |
|||
|
|||
$ax.public.fn.getCornersFromComponent = function (id) { |
|||
var element = document.getElementById(id); |
|||
var matrix = element ? $ax.public.fn.transformFromElement(element) : [1.0, 0.0, 0.0, 1.0, 0.0, 0.0]; |
|||
var currentMatrix = { m11: matrix[0], m21: matrix[1], m12: matrix[2], m22: matrix[3], tx: matrix[4], ty: matrix[5] }; |
|||
var dimensions = {}; |
|||
var axObj = $ax('#' + id); |
|||
var viewportLocation = axObj.offsetLocation(); |
|||
dimensions.left = viewportLocation.left; |
|||
dimensions.top = viewportLocation.top; |
|||
//dimensions.left = axObj.left(true);
|
|||
//dimensions.top = axObj.top(true);
|
|||
var size = axObj.size(); |
|||
dimensions.width = size.width; |
|||
dimensions.height = size.height; |
|||
//var transformMatrix1 = { m11: 1, m12: 0, m21: 0, m22: 1, tx: -invariant.x, ty: -invariant.y };
|
|||
//var transformMatrix2 = { m11: 1, m12: 0, m21: 0, m22: 1, tx: 500, ty: 500 };
|
|||
|
|||
var halfWidth = dimensions.width * 0.5; |
|||
var halfHeight = dimensions.height * 0.5; |
|||
//var preTransformTopLeft = { x: -halfWidth, y: -halfHeight };
|
|||
//var preTransformBottomLeft = { x: -halfWidth, y: halfHeight };
|
|||
var preTransformTopRight = { x: halfWidth, y: -halfHeight }; |
|||
var preTransformBottomRight = { x: halfWidth, y: halfHeight }; |
|||
|
|||
return { |
|||
//relativeTopLeft: $ax.public.fn.matrixMultiply(currentMatrix, preTransformTopLeft),
|
|||
//relativeBottomLeft: $ax.public.fn.matrixMultiply(currentMatrix, preTransformBottomLeft),
|
|||
relativeTopRight: $ax.public.fn.matrixMultiply(currentMatrix, preTransformTopRight), |
|||
relativeBottomRight: $ax.public.fn.matrixMultiply(currentMatrix, preTransformBottomRight), |
|||
centerPoint: { x: dimensions.left + halfWidth, y: dimensions.top + halfHeight } |
|||
//originalDimensions: dimensions,
|
|||
//transformShift: { x: matrix[4], y: matrix[5] }
|
|||
} |
|||
} |
|||
|
|||
|
|||
|
|||
$ax.public.fn.inversePathLengthFunction = function (pathFunction) { |
|||
// these are for computing the inverse functions of path integrals.
|
|||
|
|||
var makeDivisionNode = function(node1, node2) { |
|||
var param = 0.5 * (node1.Param + node2.Param); |
|||
var inBetweenNode = { |
|||
LowerStop: node1, |
|||
HigherStop: node2, |
|||
Param: param, |
|||
Position: pathFunction(param), |
|||
Cumulative: 0.0 |
|||
}; |
|||
var lowerDisplacement = $ax.public.fn.vectorMinus(node1.Position, inBetweenNode.Position); |
|||
inBetweenNode.LowerInterval = { |
|||
Length: $ax.public.fn.l2(lowerDisplacement.x, lowerDisplacement.y), |
|||
Node: inBetweenNode, |
|||
IsHigher: false |
|||
}; |
|||
var higherDisplacement = $ax.public.fn.vectorMinus(node2.Position, inBetweenNode.Position); |
|||
inBetweenNode.HigherInterval = { |
|||
Length: $ax.public.fn.l2(higherDisplacement.x, higherDisplacement.y), |
|||
Node: inBetweenNode, |
|||
IsHigher: true |
|||
}; |
|||
return inBetweenNode; |
|||
}; |
|||
|
|||
var expandLower = function(node) { |
|||
node.LowerChild = makeDivisionNode(node.LowerStop, node); |
|||
node.LowerChild.Parent = node; |
|||
}; |
|||
|
|||
var expandHigher = function(node) { |
|||
node.HigherChild = makeDivisionNode(node, node.HigherStop); |
|||
node.HigherChild.Parent = node; |
|||
}; |
|||
|
|||
// for this function, cumulative is a global variable
|
|||
var cumulative = 0.0; |
|||
var labelCumulativeLength = function(node) { |
|||
if(!node.LowerChild) { |
|||
node.LowerStop.Cumulative = cumulative; |
|||
cumulative += node.LowerInterval.Length; |
|||
node.Cumulative = cumulative; |
|||
} else labelCumulativeLength(node.LowerChild); |
|||
|
|||
if(!node.HigherChild) { |
|||
node.Cumulative = cumulative; |
|||
cumulative += node.HigherInterval.Length; |
|||
node.HigherStop.Cumulative = cumulative; |
|||
} else labelCumulativeLength(node.HigherChild); |
|||
}; |
|||
|
|||
var getIntervalFromPathLength = function(node, length) { |
|||
if(length < node.Cumulative) { |
|||
return node.LowerChild ? getIntervalFromPathLength(node.LowerChild, length) : node.LowerInterval; |
|||
} else return node.HigherChild ? getIntervalFromPathLength(node.HigherChild, length) : node.HigherInterval; |
|||
}; |
|||
|
|||
var intervalLowerEnd = function(interval) { |
|||
return interval.IsHigher ? interval.Node : interval.Node.LowerStop; |
|||
}; |
|||
|
|||
var intervalHigherEnd = function(interval) { |
|||
return interval.IsHigher ? interval.Node.HigherStop : interval.Node; |
|||
}; |
|||
|
|||
var getParameterFromPathLength = function (node, length) { |
|||
var interval = getIntervalFromPathLength(node, length); |
|||
var lowerNode = intervalLowerEnd(interval); |
|||
var higherNode = intervalHigherEnd(interval); |
|||
return lowerNode.Param + (higherNode.Param - lowerNode.Param) * (length - lowerNode.Cumulative) / (higherNode.Cumulative - lowerNode.Cumulative); |
|||
}; |
|||
|
|||
var insertIntoSortedList = function (longer, shorter, toInsert) { |
|||
while (true) { |
|||
if (!longer) { |
|||
longer = shorter; |
|||
shorter = shorter.NextLongest; |
|||
continue; |
|||
} else if (!shorter) longer.NextLongest = toInsert; |
|||
else { |
|||
if (longer.Length >= toInsert.Length && shorter.Length <= toInsert.Length) { |
|||
longer.NextLongest = toInsert; |
|||
toInsert.NextLongest = shorter; |
|||
} else { |
|||
longer = shorter; |
|||
shorter = shorter.NextLongest; |
|||
continue; |
|||
} |
|||
} |
|||
break; |
|||
} |
|||
} |
|||
var head = {Param: 0.0, Position: pathFunction(0.0) }; |
|||
var tail = { Param: 1.0, Position: pathFunction(1.0) }; |
|||
var root = makeDivisionNode(head, tail); |
|||
var currentCurveLength = root.LowerInterval.Length + root.HigherInterval.Length; |
|||
var longestInterval; |
|||
if (root.LowerInterval.Length < root.HigherInterval.Length) { |
|||
longestInterval = root.HigherInterval; |
|||
longestInterval.NextLongest = root.LowerInterval; |
|||
} else { |
|||
longestInterval = root.LowerInterval; |
|||
longestInterval.NextLongest = root.HigherInterval; |
|||
} |
|||
while (longestInterval.Length * 100.0 > currentCurveLength) { |
|||
var newNode; |
|||
if (longestInterval.IsHigher) { |
|||
expandHigher(longestInterval.Node); |
|||
newNode = longestInterval.Node.HigherChild; |
|||
} else { |
|||
expandLower(longestInterval.Node); |
|||
newNode = longestInterval.Node.LowerChild; |
|||
} |
|||
currentCurveLength += (newNode.LowerInterval.Length + newNode.HigherInterval.Length - longestInterval.Length); |
|||
insertIntoSortedList(null, longestInterval, newNode.LowerInterval); |
|||
insertIntoSortedList(null, longestInterval, newNode.HigherInterval); |
|||
longestInterval = longestInterval.NextLongest; |
|||
} |
|||
labelCumulativeLength(root); |
|||
|
|||
return function(lengthParam) { |
|||
return getParameterFromPathLength(root, lengthParam * cumulative); |
|||
}; |
|||
} |
|||
}); |
@ -1,53 +0,0 @@ |
|||
// ******* Object Model ******** //
|
|||
$axure.internal(function($ax) { |
|||
var _implementations = {}; |
|||
|
|||
var _initializeObject = function(type, obj) { |
|||
$.extend(obj, _implementations[type]); |
|||
}; |
|||
$ax.initializeObject = _initializeObject; |
|||
|
|||
var _model = $ax.model = {}; |
|||
|
|||
_model.idsInRdoToHideOrLimbo = function(rdoId, scriptIds) { |
|||
var rdoScriptId = $ax.repeater.getScriptIdFromElementId(rdoId); |
|||
var path = $ax.getPathFromScriptId(rdoScriptId); |
|||
|
|||
if(!scriptIds) scriptIds = []; |
|||
|
|||
var rdo = $ax.getObjectFromElementId(rdoId); |
|||
var master = $ax.pageData.masters[rdo.masterId]; |
|||
var masterChildren = master.diagram.objects; |
|||
for(var i = 0; i < masterChildren.length; i++) { |
|||
var obj = masterChildren[i]; |
|||
var objScriptIds = obj.scriptIds; |
|||
for(var j = 0; j < objScriptIds.length; j++) { |
|||
var scriptId = objScriptIds[j]; |
|||
// Anything in a layer is already handled by the layer
|
|||
if($ax.getLayerParentFromElementId(scriptId)) continue; |
|||
|
|||
// Make sure in same rdo
|
|||
var elementPath = $ax.getPathFromScriptId(scriptId); |
|||
|
|||
// This is because last part of path is for the obj itself.
|
|||
elementPath.pop(); |
|||
if(elementPath.length != path.length) continue; |
|||
var samePath = true; |
|||
for(var k = 0; k < path.length; k++) { |
|||
if(elementPath[k] != path[k]) { |
|||
samePath = false; |
|||
break; |
|||
} |
|||
} |
|||
if(!samePath) continue; |
|||
|
|||
if($ax.public.fn.IsReferenceDiagramObject(obj.type)) _model.idsInRdoToHideOrLimbo(scriptId, scriptIds); |
|||
else if(scriptIds.indexOf(scriptId) == -1) scriptIds.push(scriptId); |
|||
|
|||
break; |
|||
} |
|||
} |
|||
return scriptIds; |
|||
}; |
|||
|
|||
}); |
@ -1,467 +0,0 @@ |
|||
$axure.internal(function($ax) { |
|||
var _move = {}; |
|||
$ax.move = _move; |
|||
|
|||
var widgetMoveInfo = {}; |
|||
//register and return move info, also create container for rootlayer if needed
|
|||
$ax.move.PrepareForMove = function (id, x, y, to, options, jobj, rootLayer, skipContainerForRootLayer) { |
|||
var fixedInfo = jobj ? {} : $ax.dynamicPanelManager.getFixedInfo(id); |
|||
|
|||
var widget = $jobj(id); |
|||
var query = $ax('#' + id); |
|||
var isLayer = $ax.getTypeFromElementId(id) == $ax.constants.LAYER_TYPE; |
|||
if(!rootLayer) { |
|||
rootLayer = _move.getRootLayer(id); |
|||
if (rootLayer && !skipContainerForRootLayer) { |
|||
$ax.visibility.pushContainer(rootLayer, false); |
|||
if (isLayer) widget = $ax.visibility.applyWidgetContainer(id, true); |
|||
} |
|||
} |
|||
if (!jobj) jobj = widget; |
|||
|
|||
var horzProp = 'left'; |
|||
var vertProp = 'top'; |
|||
var offsetLocation = to ? query.offsetLocation() : undefined; |
|||
var horzX = to ? x - offsetLocation.x : x; |
|||
var vertY = to ? y - offsetLocation.y : y; |
|||
//var horzX = to ? x - query.locRelativeIgnoreLayer(false) : x;
|
|||
//var vertY = to ? y - query.locRelativeIgnoreLayer(true) : y;
|
|||
|
|||
if (fixedInfo.horizontal == 'right') { |
|||
horzProp = 'right'; |
|||
horzX = to ? $(window).width() - x - $ax.getNumFromPx(jobj.css('right')) - query.width() : -x; |
|||
var leftChanges = -horzX; |
|||
} else if(fixedInfo.horizontal == 'center') { |
|||
horzProp = 'margin-left'; |
|||
if (to) horzX = x - $(window).width() / 2; |
|||
} |
|||
|
|||
if (fixedInfo.vertical == 'bottom') { |
|||
vertProp = 'bottom'; |
|||
vertY = to ? $(window).height() - y - $ax.getNumFromPx(jobj.css('bottom')) - query.height() : -y; |
|||
var topChanges = -vertY; |
|||
} else if (fixedInfo.vertical == 'middle') { |
|||
vertProp = 'margin-top'; |
|||
if (to) vertY = y - $(window).height() / 2; |
|||
} |
|||
|
|||
//todo currently this always save the info, which is not needed for compound vector children and maybe some other cases
|
|||
//let's optimize it later, only register if registerid is valid..
|
|||
widgetMoveInfo[id] = { |
|||
x: leftChanges === undefined ? horzX : leftChanges, |
|||
y: topChanges === undefined ? vertY : topChanges, |
|||
options: options |
|||
}; |
|||
|
|||
return { |
|||
horzX: horzX, |
|||
vertY: vertY, |
|||
horzProp: horzProp, |
|||
vertProp: vertProp, |
|||
rootLayer: rootLayer, |
|||
jobj: jobj |
|||
}; |
|||
}; |
|||
$ax.move.GetWidgetMoveInfo = function() { |
|||
return $.extend({}, widgetMoveInfo); |
|||
}; |
|||
|
|||
_move.getRootLayer = function (id) { |
|||
var isLayer = $ax.getTypeFromElementId(id) == $ax.constants.LAYER_TYPE; |
|||
var rootLayer = isLayer ? id : ''; |
|||
|
|||
var parentIds = $ax('#' + id).getParents(true, '*')[0]; |
|||
for(var i = 0; i < parentIds.length; i++) { |
|||
var parentId = parentIds[i]; |
|||
// Keep climbing up layers until you hit a non-layer. At that point you have your root layer
|
|||
if($ax.public.fn.IsLayer($ax.getTypeFromElementId(parentId))) rootLayer = parentId; |
|||
else break; |
|||
} |
|||
|
|||
return rootLayer; |
|||
}; |
|||
|
|||
$ax.move.MoveWidget = function (id, x, y, options, to, animationCompleteCallback, shouldFire, jobj, skipOnMoveEvent) { |
|||
var moveInfo = $ax.move.PrepareForMove(id, x, y, to, options, jobj); |
|||
$ax.drag.LogMovedWidgetForDrag(id, options.dragInfo); |
|||
|
|||
var object = $obj(id); |
|||
if(object && $ax.public.fn.IsLayer(object.type)) { |
|||
var childrenIds = $ax.public.fn.getLayerChildrenDeep(id, true); |
|||
//don't push container when register moveinfo for child
|
|||
if(!skipOnMoveEvent) { |
|||
for(var i = 0; i < childrenIds.length; i++) $ax.move.PrepareForMove(childrenIds[i], x, y, to, options, null, moveInfo.rootLayer, true); |
|||
} |
|||
} |
|||
|
|||
//if(!moveInfo) moveInfo = _getMoveInfo(id, x, y, to, options, jobj);
|
|||
|
|||
jobj = moveInfo.jobj; |
|||
|
|||
_moveElement(id, options, animationCompleteCallback, shouldFire, jobj, moveInfo); |
|||
|
|||
if(skipOnMoveEvent) return; |
|||
$ax.event.raiseSyntheticEvent(id, "onMove"); |
|||
if(childrenIds) { |
|||
for(var i = 0; i < childrenIds.length; i++) $ax.event.raiseSyntheticEvent(childrenIds[i], 'onMove'); |
|||
} |
|||
}; |
|||
|
|||
var _moveElement = function (id, options, animationCompleteCallback, shouldFire, jobj, moveInfo){ |
|||
var cssStyles = {}; |
|||
|
|||
if(!$ax.dynamicPanelManager.isPercentWidthPanel($obj(id))) cssStyles[moveInfo.horzProp] = '+=' + moveInfo.horzX; |
|||
cssStyles[moveInfo.vertProp] = '+=' + moveInfo.vertY; |
|||
|
|||
$ax.visibility.moveMovedLocation(id, moveInfo.horzX, moveInfo.vertY); |
|||
|
|||
// I don't think root layer is necessary anymore after changes to layer container structure.
|
|||
// Wait to try removing it until more stable.
|
|||
var rootLayer = moveInfo.rootLayer; |
|||
|
|||
var query = $addAll(jobj, id); |
|||
var completeCount = query.length; |
|||
var completeAnimation = function() { |
|||
completeCount--; |
|||
if(completeCount == 0 && rootLayer) $ax.visibility.popContainer(rootLayer, false); |
|||
if(animationCompleteCallback) animationCompleteCallback(); |
|||
if(shouldFire) $ax.action.fireAnimationFromQueue(id, $ax.action.queueTypes.move); |
|||
}; |
|||
if (options.easing === 'none') { |
|||
//if not having this requestAnimationFrame causes performance issues,
|
|||
//add it back and move the above call to moveMovedLocation into it and the
|
|||
//query.animate calls below
|
|||
//window.requestAnimationFrame(function () {
|
|||
query.css(cssStyles); |
|||
if (rootLayer) $ax.visibility.popContainer(rootLayer, false); |
|||
if (animationCompleteCallback) animationCompleteCallback(); |
|||
//});
|
|||
//if this widget is inside a layer, we should just remove the layer from the queue
|
|||
if(shouldFire) $ax.action.fireAnimationFromQueue(id, $ax.action.queueTypes.move); |
|||
} else if (options.trajectory === 'straight' || moveInfo.horzX === 0 || moveInfo.vertY === 0) { |
|||
query.animate(cssStyles, { |
|||
duration: options.duration, easing: options.easing, queue: false, complete: completeAnimation}); |
|||
} else { |
|||
var initialHorzProp = $ax.getNumFromPx(query.css(moveInfo.horzProp)); |
|||
var initialVertProp = $ax.getNumFromPx(query.css(moveInfo.vertProp)); |
|||
var state = { parameter: 0 }; |
|||
var ellipseArcFunctionY = function(param) { |
|||
return { |
|||
x: initialHorzProp + (1.0 - Math.cos(param * Math.PI * 0.5)) * moveInfo.horzX, |
|||
y: initialVertProp + Math.sin(param * Math.PI * 0.5) * moveInfo.vertY |
|||
}; |
|||
}; |
|||
var ellipseArcFunctionX = function (param) { |
|||
return { |
|||
x: initialHorzProp + Math.sin(param * Math.PI * 0.5) * moveInfo.horzX, |
|||
y: initialVertProp + (1.0 - Math.cos(param * Math.PI * 0.5)) * moveInfo.vertY |
|||
}; |
|||
}; |
|||
var ellipseArcFunction = (moveInfo.horzX > 0) ^ (moveInfo.vertY > 0) ^ options.trajectory === 'arcClockwise' |
|||
? ellipseArcFunctionX : ellipseArcFunctionY; |
|||
var inverseFunction = $ax.public.fn.inversePathLengthFunction(ellipseArcFunction); |
|||
$(state).animate({ parameter: 1.0 }, { |
|||
duration: options.duration, easing: options.easing, queue: false, |
|||
step: function (now) { |
|||
var newPos = ellipseArcFunction(inverseFunction(now)); |
|||
var changeFields = {}; |
|||
changeFields[moveInfo.horzProp] = newPos.x; |
|||
changeFields[moveInfo.vertProp] = newPos.y; |
|||
query.css(changeFields); |
|||
}, |
|||
complete: completeAnimation}); |
|||
} |
|||
|
|||
// //moveinfo is used for moving 'with this'
|
|||
// var moveInfo = new Object();
|
|||
// moveInfo.x = horzX;
|
|||
// moveInfo.y = vertY;
|
|||
// moveInfo.options = options;
|
|||
// widgetMoveInfo[id] = moveInfo;
|
|||
|
|||
|
|||
}; |
|||
|
|||
_move.nopMove = function(id, options) { |
|||
var moveInfo = new Object(); |
|||
moveInfo.x = 0; |
|||
moveInfo.y = 0; |
|||
moveInfo.options = {}; |
|||
moveInfo.options.easing = 'none'; |
|||
moveInfo.options.duration = 0; |
|||
widgetMoveInfo[id] = moveInfo; |
|||
|
|||
// Layer move using container now.
|
|||
var obj = $obj(id); |
|||
if($ax.public.fn.IsLayer(obj.type)) if(options.onComplete) options.onComplete(); |
|||
|
|||
$ax.event.raiseSyntheticEvent(id, "onMove"); |
|||
}; |
|||
|
|||
//rotationDegree: total degree to rotate
|
|||
//centerPoint: the center of the circular path
|
|||
|
|||
|
|||
var _noRotateOnlyMove = function (id, moveDelta, rotatableMove, fireAnimationQueue, easing, duration, completionCallback) { |
|||
moveDelta.x += rotatableMove.x; |
|||
moveDelta.y += rotatableMove.y; |
|||
if (moveDelta.x == 0 && moveDelta.y == 0) { |
|||
if(fireAnimationQueue) { |
|||
$ax.action.fireAnimationFromQueue(id, $ax.action.queueTypes.rotate); |
|||
$ax.action.fireAnimationFromQueue(id, $ax.action.queueTypes.move); |
|||
} |
|||
if (completionCallback) completionCallback(); |
|||
} else { |
|||
$jobj(id).animate({ top: '+=' + moveDelta.y, left: '+=' + moveDelta.x }, { |
|||
duration: duration, |
|||
easing: easing, |
|||
queue: false, |
|||
complete: function () { |
|||
if(fireAnimationQueue) { |
|||
$ax.action.fireAnimationFromQueue(id, $ax.action.queueTypes.move); |
|||
$ax.action.fireAnimationFromQueue(id, $ax.action.queueTypes.rotate); |
|||
} |
|||
if (completionCallback) completionCallback(); |
|||
} |
|||
}); |
|||
} |
|||
} |
|||
|
|||
|
|||
_move.circularMove = function (id, degreeDelta, centerPoint, moveDelta, rotatableMove, resizeOffset, options, fireAnimationQueue, completionCallback, willDoRotation) { |
|||
var elem = $jobj(id); |
|||
if(!willDoRotation) elem = $addAll(elem, id); |
|||
|
|||
var moveInfo = $ax.move.PrepareForMove(id, moveDelta.x, moveDelta.y, false, options); |
|||
// If not rotating, still need to check moveDelta and may need to handle that.
|
|||
if (degreeDelta === 0) { |
|||
_noRotateOnlyMove(id, moveDelta, rotatableMove, fireAnimationQueue, options.easing, options.duration, completionCallback); |
|||
return; |
|||
} |
|||
|
|||
var stepFunc = function(newDegree) { |
|||
var deg = newDegree - rotation.degree; |
|||
var widgetCenter = $ax('#' + id).offsetBoundingRect().centerPoint; |
|||
//var widgetCenter = $ax.public.fn.getWidgetBoundingRect(id).centerPoint;
|
|||
//console.log("widget center of " + id + " x " + widgetCenter.x + " y " + widgetCenter.y);
|
|||
var widgetNewCenter = $axure.fn.getPointAfterRotate(deg, widgetCenter, centerPoint); |
|||
|
|||
// Start by getting the move not related to rotation, and make sure to update center point to move with it.
|
|||
var ratio = deg / degreeDelta; |
|||
|
|||
var xdelta = (moveDelta.x + rotatableMove.x) * ratio; |
|||
var ydelta = (moveDelta.y + rotatableMove.y) * ratio; |
|||
if(resizeOffset) { |
|||
var resizeShift = {}; |
|||
resizeShift.x = resizeOffset.x * ratio; |
|||
resizeShift.y = resizeOffset.y * ratio; |
|||
$axure.fn.getPointAfterRotate(rotation.degree, resizeShift, { x: 0, y: 0 }); |
|||
xdelta += resizeShift.x; |
|||
ydelta += resizeShift.y; |
|||
} |
|||
centerPoint.x += xdelta; |
|||
centerPoint.y += ydelta; |
|||
|
|||
// Now for the move that is rotatable, it must be rotated
|
|||
rotatableMove = $axure.fn.getPointAfterRotate(deg, rotatableMove, { x: 0, y: 0 }); |
|||
|
|||
// Now add in circular move to the mix.
|
|||
xdelta += widgetNewCenter.x - widgetCenter.x; |
|||
ydelta += widgetNewCenter.y - widgetCenter.y; |
|||
|
|||
$ax.visibility.moveMovedLocation(id, xdelta, ydelta); |
|||
|
|||
if(xdelta < 0) elem.css('left', '-=' + -xdelta); |
|||
else if(xdelta > 0) elem.css('left', '+=' + xdelta); |
|||
|
|||
if(ydelta < 0) elem.css('top', '-=' + -ydelta); |
|||
else if(ydelta > 0) elem.css('top', '+=' + ydelta); |
|||
}; |
|||
|
|||
var onComplete = function() { |
|||
if(fireAnimationQueue) $ax.action.fireAnimationFromQueue(id, $ax.action.queueTypes.move); |
|||
if(completionCallback) completionCallback(); |
|||
if(moveInfo.rootLayer) $ax.visibility.popContainer(moveInfo.rootLayer, false); |
|||
var isPercentWidthPanel = $ax.dynamicPanelManager.isPercentWidthPanel($obj(id)); |
|||
if(isPercentWidthPanel) { |
|||
$ax.dynamicPanelManager.updatePanelPercentWidth(id); |
|||
$ax.dynamicPanelManager.updatePanelContentPercentWidth(id); |
|||
} |
|||
if(elem.css('position') == 'fixed') { |
|||
if(!isPercentWidthPanel) elem.css('left', ''); |
|||
elem.css('top', ''); |
|||
} |
|||
}; |
|||
|
|||
var rotation = { degree: 0 }; |
|||
|
|||
if(!options.easing || options.easing === 'none' || options.duration <= 0) { |
|||
stepFunc(degreeDelta); |
|||
onComplete(); |
|||
} else { |
|||
$(rotation).animate({ degree: degreeDelta }, { |
|||
duration: options.duration, |
|||
easing: options.easing, |
|||
queue: false, |
|||
step: stepFunc, |
|||
complete: onComplete |
|||
}); |
|||
} |
|||
}; |
|||
|
|||
//rotate a widget by degree, center is 50% 50%
|
|||
_move.rotate = function (id, degree, easing, duration, to, shouldFire, completionCallback) { |
|||
var currentDegree = _move.getRotationDegree(id); |
|||
if(to) degree = degree - currentDegree; |
|||
|
|||
if(degree === 0) { |
|||
if (shouldFire) $ax.action.fireAnimationFromQueue(id, $ax.action.queueTypes.rotate); |
|||
return; |
|||
} |
|||
|
|||
var query = $jobj(id); |
|||
var stepFunc = function(now) { |
|||
var degreeDelta = now - rotation.degree; |
|||
var newDegree = currentDegree + degreeDelta; |
|||
query.css($ax.public.fn.setTransformHowever("rotate(" + newDegree + "deg)")); |
|||
currentDegree = newDegree; |
|||
}; |
|||
|
|||
var onComplete = function() { |
|||
if(shouldFire) { |
|||
$ax.action.fireAnimationFromQueue($ax.public.fn.compoundIdFromComponent(id), $ax.action.queueTypes.rotate); |
|||
} |
|||
if(completionCallback) completionCallback(); |
|||
|
|||
$ax.annotation.adjustIconLocation(id); |
|||
}; |
|||
|
|||
var rotation = { degree: 0 }; |
|||
|
|||
$ax.visibility.setRotatedAngle(id, currentDegree + degree); |
|||
|
|||
//if no animation, setting duration to 1, to prevent RangeError in rotation loops without animation
|
|||
if(!easing || easing === 'none' || duration <= 0) { |
|||
stepFunc(degree); |
|||
onComplete(); |
|||
} else { |
|||
$(rotation).animate({ degree: degree }, { |
|||
duration: duration, |
|||
easing: easing, |
|||
queue: false, |
|||
step: stepFunc, |
|||
complete: onComplete |
|||
}); |
|||
} |
|||
}; |
|||
|
|||
_move.compoundRotateAround = function (id, degreeDelta, centerPoint, moveDelta, rotatableMove, resizeOffset, easing, duration, fireAnimationQueue, completionCallback) { |
|||
if (degreeDelta === 0) { |
|||
_noRotateOnlyMove($ax.public.fn.compoundIdFromComponent(id), moveDelta, rotatableMove, fireAnimationQueue, easing, duration, completionCallback, $ax.action.queueTypes.rotate); |
|||
return; |
|||
} |
|||
var elem = $jobj(id); |
|||
var rotation = { degree: 0 }; |
|||
|
|||
if (!easing || easing === 'none' || duration <= 0) { |
|||
duration = 1; |
|||
easing = 'linear'; //it doesn't matter anymore here...
|
|||
} |
|||
|
|||
var originalWidth = $ax.getNumFromPx(elem.css('width')); |
|||
var originalHeight = $ax.getNumFromPx(elem.css('height')); |
|||
var originalLeft = $ax.getNumFromPx(elem.css('left')); |
|||
var originalTop = $ax.getNumFromPx(elem.css('top')); |
|||
|
|||
$(rotation).animate({ degree: degreeDelta }, { |
|||
duration: duration, |
|||
easing: easing, |
|||
queue: false, |
|||
step: function (newDegree) { |
|||
var transform = $ax.public.fn.transformFromElement(elem[0]); |
|||
var originalCenter = { x: originalLeft + 0.5 * originalWidth, y: originalTop + 0.5 * originalHeight}; |
|||
var componentCenter = { x: originalCenter.x + transform[4], y: originalCenter.y + transform[5] }; |
|||
var deg = newDegree - rotation.degree; |
|||
var ratio = deg / degreeDelta; |
|||
var xdelta = (moveDelta.x + rotatableMove.x) * ratio; |
|||
var ydelta = (moveDelta.y + rotatableMove.y) * ratio; |
|||
if (resizeOffset) { |
|||
var resizeShift = {}; |
|||
resizeShift.x = resizeOffset.x * ratio; |
|||
resizeShift.y = resizeOffset.y * ratio; |
|||
$axure.fn.getPointAfterRotate(rotation.degree, resizeShift, { x: 0, y: 0 }); |
|||
xdelta += resizeShift.x; |
|||
ydelta += resizeShift.y; |
|||
} |
|||
|
|||
var rotationMatrix = $ax.public.fn.rotationMatrix(deg); |
|||
var compositionTransform = $ax.public.fn.matrixMultiplyMatrix(rotationMatrix, |
|||
{ m11: transform[0], m21: transform[1], m12: transform[2], m22: transform[3] }); |
|||
|
|||
//console.log("widget center of " + id + " x " + widgetCenter.x + " y " + widgetCenter.y);
|
|||
var widgetNewCenter = $axure.fn.getPointAfterRotate(deg, componentCenter, centerPoint); |
|||
var newMatrix = $ax.public.fn.matrixString(compositionTransform.m11, compositionTransform.m21, compositionTransform.m12, compositionTransform.m22, |
|||
widgetNewCenter.x - originalCenter.x + xdelta, widgetNewCenter.y - originalCenter.y + ydelta); |
|||
elem.css($ax.public.fn.setTransformHowever(newMatrix)); |
|||
}, |
|||
complete: function () { |
|||
if (fireAnimationQueue) { |
|||
$ax.action.fireAnimationFromQueue(elem.parent()[0].id, $ax.action.queueTypes.rotate); |
|||
} |
|||
|
|||
if(completionCallback) completionCallback(); |
|||
} |
|||
}); |
|||
}; |
|||
|
|||
_move.getRotationDegreeFromElement = function(element) { |
|||
if(element == null) return NaN; |
|||
|
|||
var transformString = element.style['transform'] || |
|||
element.style['-o-transform'] || |
|||
element.style['-ms-transform'] || |
|||
element.style['-moz-transform'] || |
|||
element.style['-webkit-transform']; |
|||
|
|||
if(transformString) { |
|||
var rotateRegex = /rotate\(([-?0-9]+)deg\)/; |
|||
var degreeMatch = rotateRegex.exec(transformString); |
|||
if(degreeMatch && degreeMatch[1]) return parseFloat(degreeMatch[1]); |
|||
} |
|||
|
|||
if(window.getComputedStyle) { |
|||
var st = window.getComputedStyle(element, null); |
|||
} else { |
|||
console.log('rotation is not supported for ie 8 and below in this version of axure rp'); |
|||
return 0; |
|||
} |
|||
|
|||
var tr = st.getPropertyValue("transform") || |
|||
st.getPropertyValue("-o-transform") || |
|||
st.getPropertyValue("-ms-transform") || |
|||
st.getPropertyValue("-moz-transform") || |
|||
st.getPropertyValue("-webkit-transform"); |
|||
|
|||
if(!tr || tr === 'none') return 0; |
|||
var values = tr.split('(')[1]; |
|||
values = values.split(')')[0], |
|||
values = values.split(','); |
|||
|
|||
var a = values[0]; |
|||
var b = values[1]; |
|||
|
|||
var radians = Math.atan2(b, a); |
|||
if(radians < 0) { |
|||
radians += (2 * Math.PI); |
|||
} |
|||
|
|||
return radians * (180 / Math.PI); |
|||
}; |
|||
|
|||
_move.getRotationDegree = function(elementId) { |
|||
if($ax.public.fn.IsLayer($obj(elementId).type)) { |
|||
return $jobj(elementId).data('layerDegree'); |
|||
} |
|||
return _move.getRotationDegreeFromElement(document.getElementById(elementId)); |
|||
} |
|||
}); |
@ -1,94 +0,0 @@ |
|||
// ******* Recording MANAGER ******** //
|
|||
|
|||
$axure.internal(function($ax) { |
|||
var _recording = $ax.recording = {}; |
|||
|
|||
$ax.recording.recordEvent = function(element, eventInfo, axEventObject, timeStamp) { |
|||
|
|||
var elementHtml = $jobj(element); |
|||
var className = elementHtml.attr('class'); |
|||
var inputValue; |
|||
|
|||
if(className === 'ax_checkbox') { |
|||
inputValue = elementHtml.find('#' + element + '_input')[0].checked; |
|||
eventInfo.inputType = className; |
|||
eventInfo.inputValue = inputValue; |
|||
} |
|||
|
|||
if(className === 'ax_text_field') { |
|||
inputValue = elementHtml.find('#' + element + '_input').val(); |
|||
eventInfo.inputType = className; |
|||
eventInfo.inputValue = inputValue; |
|||
} |
|||
|
|||
|
|||
var scriptId = $ax.repeater.getScriptIdFromElementId(element); |
|||
var diagramObjectPath = $ax.getPathFromScriptId(scriptId); |
|||
var form = { |
|||
recordingId: $ax.recording.recordingId, |
|||
elementID: element, |
|||
eventType: axEventObject.description, |
|||
'eventInfo': eventInfo, |
|||
// eventObject: axEventObject,
|
|||
'timeStamp': timeStamp, |
|||
'path': diagramObjectPath |
|||
// ,
|
|||
// 'trigger': function() {
|
|||
// $ax.event.handleEvent(element, eventInfo, axEventObject);
|
|||
// return false;
|
|||
// }
|
|||
}; |
|||
|
|||
$ax.messageCenter.postMessage('logEvent', form); |
|||
}; |
|||
|
|||
|
|||
$ax.recording.maybeRecordEvent = function(element, eventInfo, axEventObject, timeStamp) { |
|||
}; |
|||
|
|||
|
|||
$ax.recording.recordingId = ""; |
|||
$ax.recording.recordingName = ""; |
|||
|
|||
$ax.messageCenter.addMessageListener(function(message, data) { |
|||
if(message === 'startRecording') { |
|||
$ax.recording.maybeRecordEvent = $ax.recording.recordEvent; |
|||
$ax.recording.recordingId = data.recordingId; |
|||
$ax.recording.recordingName = data.recordingName; |
|||
} else if(message === 'stopRecording') { |
|||
$ax.recording.maybeRecordEvent = function(element, eventInfo, axEventObject, timeStamp) { |
|||
}; |
|||
|
|||
} |
|||
else if(message === 'playEvent') { |
|||
|
|||
var eventType = makeFirstLetterLower(data.eventType); |
|||
var inputElement; |
|||
|
|||
var dObj = data.element === '' ? $ax.pageData.page : $ax.getObjectFromElementId(data.element); |
|||
if(!data.axEventObject) { |
|||
data.axEventObject = dObj && dObj.interactionMap && dObj.interactionMap[eventType]; |
|||
} |
|||
|
|||
data.eventInfo.thiswidget = $ax.getWidgetInfo(data.element); |
|||
data.eventInfo.item = $ax.getItemInfo(data.element); |
|||
|
|||
if(data.eventInfo.inputType && data.eventInfo.inputType === 'ax_checkbox') { |
|||
inputElement = $jobj(data.element + '_input'); |
|||
inputElement[0].checked = data.eventInfo.inputValue; |
|||
} |
|||
|
|||
if(data.eventInfo.inputType && data.eventInfo.inputType === 'ax_text_field') { |
|||
inputElement = $jobj(data.element + '_input'); |
|||
inputElement.val(data.eventInfo.inputValue); |
|||
} |
|||
|
|||
$ax.event.handleEvent(data.element, data.eventInfo, data.axEventObject, false, true); |
|||
} |
|||
}); |
|||
|
|||
var makeFirstLetterLower = function(eventName) { |
|||
return eventName.substr(0, 1).toLowerCase() + eventName.substr(1); |
|||
}; |
|||
|
|||
}); |
@ -1,241 +0,0 @@ |
|||
|
|||
$axure.internal(function($ax) { |
|||
var funcs = {}; |
|||
|
|||
var weekday = new Array(7); |
|||
weekday[0] = "Sunday"; |
|||
weekday[1] = "Monday"; |
|||
weekday[2] = "Tuesday"; |
|||
weekday[3] = "Wednesday"; |
|||
weekday[4] = "Thursday"; |
|||
weekday[5] = "Friday"; |
|||
weekday[6] = "Saturday"; |
|||
|
|||
funcs.getDayOfWeek = function() { |
|||
return _getDayOfWeek(this.getDay()); |
|||
}; |
|||
|
|||
var _getDayOfWeek = $ax.getDayOfWeek = function(day) { |
|||
return weekday[day]; |
|||
}; |
|||
|
|||
var month = new Array(12); |
|||
month[0] = "January"; |
|||
month[1] = "February"; |
|||
month[2] = "March"; |
|||
month[3] = "April"; |
|||
month[4] = "May"; |
|||
month[5] = "June"; |
|||
month[6] = "July"; |
|||
month[7] = "August"; |
|||
month[8] = "September"; |
|||
month[9] = "October"; |
|||
month[10] = "November"; |
|||
month[11] = "December"; |
|||
|
|||
funcs.getMonthName = function() { |
|||
return _getMonthName(this.getMonth()); |
|||
}; |
|||
|
|||
var _getMonthName = $ax.getMonthName = function(monthNum) { |
|||
return month[monthNum]; |
|||
}; |
|||
|
|||
funcs.getMonth = function() { |
|||
return this.getMonth() + 1; |
|||
}; |
|||
|
|||
funcs.addYears = function(years) { |
|||
var retVal = new Date(this.valueOf()); |
|||
retVal.setFullYear(this.getFullYear() + Number(years)); |
|||
return retVal; |
|||
}; |
|||
|
|||
funcs.addMonths = function(months) { |
|||
var retVal = new Date(this.valueOf()); |
|||
retVal.setMonth(this.getMonth() + Number(months)); |
|||
return retVal; |
|||
}; |
|||
|
|||
funcs.addDays = function(days) { |
|||
var retVal = new Date(this.valueOf()); |
|||
retVal.setDate(this.getDate() + Number(days)); |
|||
return retVal; |
|||
}; |
|||
|
|||
funcs.addHours = function(hours) { |
|||
var retVal = new Date(this.valueOf()); |
|||
retVal.setHours(this.getHours() + Number(hours)); |
|||
return retVal; |
|||
}; |
|||
|
|||
funcs.addMinutes = function(minutes) { |
|||
var retVal = new Date(this.valueOf()); |
|||
retVal.setMinutes(this.getMinutes() + Number(minutes)); |
|||
return retVal; |
|||
}; |
|||
|
|||
funcs.addSeconds = function(seconds) { |
|||
var retVal = new Date(this.valueOf()); |
|||
retVal.setSeconds(this.getSeconds() + Number(seconds)); |
|||
return retVal; |
|||
}; |
|||
|
|||
funcs.addMilliseconds = function(milliseconds) { |
|||
var retVal = new Date(this.valueOf()); |
|||
retVal.setMilliseconds(this.getMilliseconds() + Number(milliseconds)); |
|||
return retVal; |
|||
}; |
|||
|
|||
var _stoHandlers = {}; |
|||
|
|||
_stoHandlers.literal = function(sto, scope, eventInfo) { |
|||
return sto.value; |
|||
}; |
|||
|
|||
//need angle bracket syntax because var is a reserved word
|
|||
_stoHandlers['var'] = function(sto, scope, eventInfo) { |
|||
// Can't us 'A || B' here, because the first value can be false, true, or empty string and still be valid.
|
|||
var retVal = scope.hasOwnProperty(sto.name) ? scope[sto.name] : $ax.globalVariableProvider.getVariableValue(sto.name, eventInfo); |
|||
// Handle desired type here?
|
|||
|
|||
if(retVal && retVal.exprType) { |
|||
retVal = $ax.expr.evaluateExpr(retVal, eventInfo); |
|||
} |
|||
|
|||
if((sto.desiredType == 'int' || sto.desiredType == 'float')) { |
|||
var num = new Number(retVal); |
|||
retVal = isNaN(num.valueOf()) ? retVal : num; |
|||
} |
|||
|
|||
|
|||
return retVal; |
|||
}; |
|||
|
|||
//TODO: Perhaps repeaterId can be detirmined at generation, and stored in the sto info.
|
|||
_stoHandlers.item = function(sto, scope, eventInfo, prop) { |
|||
prop = prop || (eventInfo.data ? 'data' : eventInfo.link ? 'url' : eventInfo.image ? 'img' : 'text'); |
|||
var id = sto.isTarget || !$ax.repeater.hasData(eventInfo.srcElement, sto.name) ? eventInfo.targetElement : eventInfo.srcElement; |
|||
return getData(eventInfo, id, sto.name, prop); |
|||
}; |
|||
|
|||
var getData = function(eventInfo, id, name, prop) { |
|||
var repeaterId = $ax.getParentRepeaterFromScriptId($ax.repeater.getScriptIdFromElementId(id)); |
|||
var itemId = $ax.repeater.getItemIdFromElementId(id); |
|||
return $ax.repeater.getData(eventInfo, repeaterId, itemId, name, prop); |
|||
}; |
|||
|
|||
_stoHandlers.paren = function(sto, scope, eventInfo) { |
|||
return _evaluateSTO(sto.innerSTO, scope, eventInfo); |
|||
}; |
|||
|
|||
_stoHandlers.fCall = function(sto, scope, eventInfo) { |
|||
//TODO: [mas] handle required type
|
|||
var thisObj = _evaluateSTO(sto.thisSTO, scope, eventInfo); |
|||
if(sto.thisSTO.desiredType == 'string' && sto.thisSTO.computedType != 'string') thisObj = thisObj.toString(); |
|||
|
|||
var args = []; |
|||
for(var i = 0; i < sto.arguments.length; i++) { |
|||
args[i] = _evaluateSTO(sto.arguments[i], scope, eventInfo); |
|||
} |
|||
var fn = (funcs.hasOwnProperty(sto.func) && funcs[sto.func]) || thisObj[sto.func]; |
|||
return fn.apply(thisObj, args); |
|||
}; |
|||
|
|||
_stoHandlers.propCall = function(sto, scope, eventInfo) { |
|||
//TODO: [mas] handle required type
|
|||
if((sto.prop == 'url' || sto.prop == 'img') && sto.thisSTO.sto == 'item') return _stoHandlers.item(sto.thisSTO, scope, eventInfo, sto.prop); |
|||
var thisObj = _evaluateSTO(sto.thisSTO, scope, eventInfo); |
|||
|
|||
// calculate cursor offset for elements that are located relative to their parents
|
|||
if (sto.thisSTO.name == 'cursor') { |
|||
var cursorOffset = $ax.public.fn.getCursorOffset(eventInfo.targetElement); |
|||
thisObj = { |
|||
x: thisObj.x - cursorOffset.x, |
|||
y: thisObj.y - cursorOffset.y, |
|||
}; |
|||
} |
|||
|
|||
var prop = thisObj[sto.prop] instanceof Function ? thisObj[sto.prop]() : thisObj[sto.prop]; |
|||
return prop; |
|||
}; |
|||
|
|||
var _binOps = {}; |
|||
_binOps['+'] = function(left, right) { |
|||
if(left instanceof Date) return addDayToDate(left, right); |
|||
if(right instanceof Date) return addDayToDate(right, left); |
|||
|
|||
var num = Number(left) + Number(right); |
|||
return isNaN(num) ? (String(left) + String(right)) : num; |
|||
}; |
|||
_binOps['-'] = function(left, right) { |
|||
if(left instanceof Date) return addDayToDate(left, -right); |
|||
return left - right; |
|||
}; |
|||
_binOps['*'] = function(left, right) { return Number(left) * Number(right); }; |
|||
_binOps['/'] = function(left, right) { return Number(left) / Number(right); }; |
|||
_binOps['%'] = function(left, right) { return Number(left) % Number(right); }; |
|||
_binOps['=='] = function(left, right) { return _getBool(left) == _getBool(right); }; |
|||
_binOps['!='] = function(left, right) { return _getBool(left) != _getBool(right); }; |
|||
_binOps['<'] = function(left, right) { return Number(left) < Number(right); }; |
|||
_binOps['<='] = function(left, right) { return Number(left) <= Number(right); }; |
|||
_binOps['>'] = function(left, right) { return Number(left) > Number(right); }; |
|||
_binOps['>='] = function(left, right) { return Number(left) >= Number(right); }; |
|||
_binOps['&&'] = function(left, right) { return _getBool(left) && _getBool(right); }; |
|||
_binOps['||'] = function(left, right) { return _getBool(left) || _getBool(right); }; |
|||
|
|||
// TODO: Move this to generic place to be used.
|
|||
var addDayToDate = function(date, days) { |
|||
var retVal = new Date(date.valueOf()); |
|||
retVal.setDate(date.getDate() + days); |
|||
return retVal; |
|||
}; |
|||
|
|||
var _unOps = {}; |
|||
_unOps['+'] = function(arg) { return +arg; }; |
|||
_unOps['-'] = function(arg) { return -arg; }; |
|||
_unOps['!'] = function(arg) { return !_getBool(arg); }; |
|||
|
|||
_stoHandlers.binOp = function(sto, scope, eventInfo) { |
|||
var left = _evaluateSTO(sto.leftSTO, scope, eventInfo); |
|||
var right = _evaluateSTO(sto.rightSTO, scope, eventInfo); |
|||
return _binOps[sto.op](left, right); |
|||
}; |
|||
|
|||
_stoHandlers.unOp = function(sto, scope, eventInfo) { |
|||
var input = _evaluateSTO(sto.inputSTO, scope, eventInfo); |
|||
return _unOps[sto.op](input); |
|||
}; |
|||
|
|||
var _getBool = function(val) { |
|||
var lowerVal = val.toLowerCase ? val.toLowerCase() : val; |
|||
return lowerVal == "false" ? false : lowerVal == "true" ? true : val; |
|||
}; |
|||
$ax.getBool = _getBool; |
|||
|
|||
var _evaluateSTO = function(sto, scope, eventInfo) { |
|||
if(sto.sto == 'error') return undefined; |
|||
return _tryEscapeRichText(castSto(_stoHandlers[sto.sto](sto, scope, eventInfo), sto), eventInfo); |
|||
}; |
|||
$ax.evaluateSTO = _evaluateSTO; |
|||
|
|||
var castSto = function(val, sto) { |
|||
var type = sto.computedType || sto.desiredType; |
|||
if(type == 'string') val = String(val); |
|||
else if(type == 'date' && !(val instanceof Date)) val = new Date(val); |
|||
else if(type == 'int' || type == 'float') val = Number(val); |
|||
else if(type == 'bool') val = Boolean(val); |
|||
|
|||
return val; |
|||
}; |
|||
|
|||
var _tryEscapeRichText = function(text, eventInfo) { |
|||
return eventInfo.htmlLiteral ? _escapeRichText(text) : text; |
|||
}; |
|||
|
|||
var _escapeRichText = function(text) { |
|||
if(typeof (text) != 'string') return text; |
|||
|
|||
return text.replace('<', '<'); |
|||
}; |
|||
}); |
@ -1,189 +0,0 @@ |
|||
// This is actually for BOTH trees and menus
|
|||
$axure.internal(function($ax) { |
|||
var _tree = $ax.tree = {}; |
|||
var _menu = $ax.menu = {}; |
|||
|
|||
$ax.menu.InitializeSubmenu = function(subMenuId, cellId) { |
|||
var $submenudiv = $('#' + subMenuId); |
|||
|
|||
//mouseenter and leave for parent table cell
|
|||
$('#' + cellId).mouseenter(function(e) { |
|||
//show current submenu
|
|||
// var submenuElement = document.getElementById(subMenuId);
|
|||
// if($ax.visibility.IsVisible(submenuElement) && submenuElement.style.display !== 'none') return;
|
|||
$ax.visibility.SetIdVisible(subMenuId, true); |
|||
$ax.legacy.BringToFront(subMenuId); |
|||
//$submenudiv.find('.menu_item').each(function() {
|
|||
// $ax.style.updateTextAlignmentForVisibility($ax.GetTextPanelId($(this).attr('id')));
|
|||
//});
|
|||
_fireEventForSubmenu(subMenuId, "onShow"); |
|||
|
|||
}).mouseleave(function (e) { |
|||
var offset = $submenudiv.offset(); |
|||
var subcontwidth = $submenudiv.width(); |
|||
var subcontheight = $submenudiv.height(); |
|||
//If mouse is not within the submenu (added 3 pixel margin to top and left calculations), then close the submenu...
|
|||
if(e.pageX + 3 < offset.left || e.pageX > offset.left + subcontwidth || e.pageY + 3 < offset.top || e.pageY > offset.top + subcontheight) { |
|||
$submenudiv.find('.sub_menu').addBack().each(function () { |
|||
// if(!$ax.visibility.IsVisible(this)) return;
|
|||
$ax.visibility.SetVisible(this, false); |
|||
_fireEventForSubmenu(subMenuId, "onHide"); |
|||
}); |
|||
$ax.style.SetWidgetHover(cellId, false); |
|||
} |
|||
}); |
|||
|
|||
$submenudiv.css('display', 'none'); |
|||
|
|||
//mouseleave for submenu
|
|||
$submenudiv.mouseleave(function(e) { |
|||
//close this menu and all menus below it
|
|||
$(this).find('.sub_menu').addBack().css({ 'visibility': 'hidden', 'display': 'none' }).each(function () { |
|||
// if(!$ax.visibility.IsVisible(this)) return;
|
|||
_fireEventForSubmenu(this.id, "onHide"); |
|||
}); |
|||
$ax.style.SetWidgetHover(cellId, false); |
|||
}); |
|||
}; |
|||
|
|||
var _fireEventForSubmenu = function(targetId, eventName) { |
|||
var diagramObject = $ax.getObjectFromElementId(targetId); |
|||
var event = diagramObject.interactionMap && diagramObject.interactionMap[eventName]; |
|||
if(event) { |
|||
var eventInfo = $ax.getEventInfoFromEvent($ax.getjBrowserEvent(), false, targetId); |
|||
$ax.event.handleEvent(targetId, eventInfo, event, false, true); |
|||
} |
|||
} |
|||
|
|||
function IsNodeVisible(nodeId) { |
|||
var current = window.document.getElementById(nodeId); |
|||
var parent = current.parentNode; |
|||
|
|||
//move all the parent's children that are below the node and their annotations
|
|||
while(!$(current).hasClass("treeroot")) { |
|||
if(!$ax.visibility.IsVisible(parent)) return false; |
|||
current = parent; |
|||
parent = parent.parentNode; |
|||
} |
|||
return true; |
|||
} |
|||
|
|||
$ax.tree.ExpandNode = function(nodeId, childContainerId, plusMinusId) { |
|||
var container = window.document.getElementById(childContainerId); |
|||
if(!container || $ax.visibility.IsVisible(container)) return; |
|||
$ax.visibility.SetVisible(container, true); |
|||
|
|||
if(plusMinusId != '') $ax.style.SetWidgetSelected(plusMinusId, true); |
|||
|
|||
var delta = _getExpandCollapseDelta(nodeId, childContainerId); |
|||
|
|||
var isVisible = IsNodeVisible(nodeId); |
|||
var current = window.document.getElementById(nodeId); |
|||
var parent = current.parentNode; |
|||
|
|||
//move all the parent's children that are below the node and their annotations
|
|||
while(!$(current).hasClass("treeroot")) { |
|||
var after = false; |
|||
var i = 0; |
|||
for(i = 0; i < parent.childNodes.length; i++) { |
|||
var child = parent.childNodes[i]; |
|||
if(after && child.id && $(child).hasClass("treenode")) { |
|||
var elementId = child.id; |
|||
child.style.top = $ax.getNumFromPx($(child).css('top')) + delta + 'px'; |
|||
var ann = window.document.getElementById(elementId + "_ann"); |
|||
if (ann) ann.style.top = $ax.getNumFromPx($(ann).css('top')) + delta + 'px'; |
|||
} |
|||
if(child == current) after = true; |
|||
} |
|||
current = parent; |
|||
parent = parent.parentNode; |
|||
if(!isVisible && $ax.visibility.IsVisible(parent)) break; |
|||
} |
|||
}; |
|||
|
|||
$ax.tree.CollapseNode = function(nodeId, childContainerId, plusMinusId) { |
|||
var container = window.document.getElementById(childContainerId); |
|||
if(!container || !$ax.visibility.IsVisible(container)) return; |
|||
|
|||
if(plusMinusId != '') $ax.style.SetWidgetSelected(plusMinusId, false); |
|||
|
|||
var delta = _getExpandCollapseDelta(nodeId, childContainerId); |
|||
|
|||
//hide it after getting the delta, otherwise the delta can't be calculated (offsetParent is null)
|
|||
$ax.visibility.SetVisible(container, false); |
|||
|
|||
var isVisible = IsNodeVisible(nodeId); |
|||
var current = window.document.getElementById(nodeId); |
|||
var parent = current.parentNode; |
|||
|
|||
//move all the parent's children that are below the node and their annotations
|
|||
while(!$(current).hasClass("treeroot")) { |
|||
var after = false; |
|||
var i = 0; |
|||
for(i = 0; i < parent.childNodes.length; i++) { |
|||
var child = parent.childNodes[i]; |
|||
if(after && child.id && $(child).hasClass("treenode")) { |
|||
var elementId = child.id; |
|||
child.style.top = $ax.getNumFromPx($(child).css('top')) - delta + 'px'; |
|||
var ann = window.document.getElementById(elementId + "_ann"); |
|||
if (ann) ann.style.top = $ax.getNumFromPx($(ann).css('top')) - delta + 'px'; |
|||
} |
|||
if(child == current) after = true; |
|||
} |
|||
current = parent; |
|||
parent = current.parentNode; |
|||
if(!isVisible && $ax.visibility.IsVisible(parent)) break; |
|||
} |
|||
}; |
|||
|
|||
var _getExpandCollapseDelta = function(nodeId, childContainerId) { |
|||
return _getChildContainerHeightHelper(childContainerId); |
|||
}; |
|||
|
|||
var _getChildContainerHeightHelper = function(childContainerId) { |
|||
var height = 0; |
|||
$('#' + childContainerId).children().each(function() { |
|||
if($(this).hasClass("treenode")) { |
|||
height += $(this).height(); |
|||
var subContainer = window.document.getElementById(this.id + '_children'); |
|||
if(subContainer && $ax.visibility.IsVisible(subContainer)) { |
|||
height += _getChildContainerHeightHelper(subContainer.id); |
|||
} |
|||
} |
|||
}); |
|||
return height; |
|||
}; |
|||
|
|||
$ax.tree.InitializeTreeNode = function(nodeId, plusminusid, childContainerId, selectText) { |
|||
var childContainer = window.document.getElementById(childContainerId); |
|||
if(childContainer) { |
|||
//relying on the html generator to put this inline so we know to collapse by default
|
|||
var isCollapsed = childContainer.style.visibility == "hidden"; |
|||
if(isCollapsed) $ax.visibility.SetVisible(childContainer, false); |
|||
|
|||
if(!isCollapsed && plusminusid != '') $ax.style.SetWidgetSelected(plusminusid, true); |
|||
} |
|||
|
|||
if(plusminusid != '') { |
|||
$jobj(plusminusid).click(function() { |
|||
var visibleSet = $ax.visibility.IsIdVisible(childContainerId); |
|||
|
|||
if(visibleSet) $ax.tree.CollapseNode(nodeId, childContainerId, plusminusid); |
|||
else $ax.tree.ExpandNode(nodeId, childContainerId, plusminusid); |
|||
$ax.tree.SelectTreeNode(nodeId, true); |
|||
|
|||
return false; |
|||
}).css('cursor', 'default'); |
|||
} |
|||
}; |
|||
|
|||
var _getButtonShapeId = function(id) { |
|||
var obj = $obj(id); |
|||
return $ax.public.fn.IsTreeNodeObject(obj.type) ? $ax.getElementIdFromPath([obj.buttonShapeId], { relativeTo: id }) : id; |
|||
}; |
|||
|
|||
$ax.tree.SelectTreeNode = function(id, selected) { |
|||
$ax.style.SetWidgetSelected(_getButtonShapeId(id), selected); |
|||
}; |
|||
|
|||
}); |
@ -1,99 +0,0 @@ |
|||
// ******* Deep Copy ******** //
|
|||
$axure.internal(function($ax) { |
|||
// TODO: [ben] Ah, infinite loops cause major issues here. Tried saving objects we've already hit, but that didn't seem to work (at least at my first shot).
|
|||
// TODO: [ben] To continue from above, added a filter to filter out problem keys. Will need a better way of sorting this out eventually.
|
|||
var _deepCopy = function (original, trackCopies, filter) { |
|||
if(trackCopies) { |
|||
var index = _getCopyIndex(original); |
|||
if(index != -1) return _originalToCopy[index][1]; |
|||
} |
|||
var isArray = original instanceof Array; |
|||
var isObject = !(original instanceof Function) && !(original instanceof Date) && (original instanceof Object); |
|||
if(!isArray && !isObject) return original; |
|||
var copy = isArray ? [] : { }; |
|||
if(trackCopies) _originalToCopy.push([original, copy]); |
|||
isArray ? deepCopyArray(original, trackCopies, copy, filter) : deepCopyObject(original, trackCopies, copy, filter); |
|||
return copy; |
|||
}; |
|||
$ax.deepCopy = _deepCopy; |
|||
|
|||
// Hacky way to copy event info. Copying dragInfo causes major issues due to infinite loops
|
|||
// Hashmap doesn't map objects well. It just toStrings them, making them all the same key. This has to be slow...
|
|||
var _originalToCopy = []; |
|||
var _getCopyIndex = function(original) { |
|||
for(var i = 0; i < _originalToCopy.length; i++) if(original === _originalToCopy[i][0]) return i; |
|||
return -1; |
|||
}; |
|||
|
|||
$ax.eventCopy = function(eventInfo) { |
|||
var copy = _deepCopy(eventInfo, true, ['dragInfo', 'elementQuery', 'obj']); |
|||
// reset the map. TODO: May need to reset elsewhere too, but this is the only way it's used currently
|
|||
_originalToCopy = []; |
|||
|
|||
return copy; |
|||
}; |
|||
|
|||
var deepCopyArray = function(original, trackCopies, copy, filter) { |
|||
for(var i = 0; i < original.length; i++) { |
|||
copy[i] = _deepCopy(original[i], trackCopies, filter); |
|||
} |
|||
}; |
|||
|
|||
var deepCopyObject = function(original, trackCopies, copy, filter) { |
|||
for(var key in original) { |
|||
if(!original.hasOwnProperty(key)) continue; // Continue if the prop was not put there like a dictionary, but just a native part of the object
|
|||
|
|||
if(filter && filter.indexOf[key] != -1) copy[key] = original[key]; // If that key is filtered out, skip recursion on it.
|
|||
else copy[key] = _deepCopy(original[key], trackCopies, filter); |
|||
} |
|||
}; |
|||
|
|||
// Our implementation of splice because it is broken in IE8...
|
|||
$ax.splice = function(array, startIndex, count) { |
|||
var retval = []; |
|||
if(startIndex >= array.length || startIndex < 0 || count == 0) return retval; |
|||
if(!count || startIndex + count > array.length) count = array.length - startIndex; |
|||
for(var i = 0; i < count; i++) retval[i] = array[startIndex + i]; |
|||
for(i = startIndex + count; i < array.length; i++) array[i - count] = array[i]; |
|||
for(i = 0; i < count; i++) array.pop(); |
|||
return retval; |
|||
}; |
|||
}); |
|||
|
|||
|
|||
|
|||
// ******* Flow Shape Links ******** //
|
|||
$axure.internal(function($ax) { |
|||
|
|||
$(window.document).ready(function() { |
|||
if (!$ax.document.configuration.linkFlowsToPages && !$ax.document.configuration.linkFlowsToPagesNewWindow) return; |
|||
|
|||
$ax(function (dObj) { return ($ax.public.fn.IsVector(dObj.type) || $ax.public.fn.IsSnapshot(dObj.type)) && dObj.referencePageUrl; }).each(function (dObj, elementId) { |
|||
|
|||
var elementIdQuery = $('#' + elementId); |
|||
|
|||
if($ax.document.configuration.linkFlowsToPages && !$ax.event.HasClick(dObj)) { |
|||
elementIdQuery.css("cursor", "pointer"); |
|||
elementIdQuery.click(function() { |
|||
$ax.navigate({ |
|||
url: dObj.referencePageUrl, |
|||
target: "current", |
|||
includeVariables: true |
|||
}); |
|||
}); |
|||
} |
|||
|
|||
if($ax.document.configuration.linkFlowsToPagesNewWindow) { |
|||
$('#' + elementId + "_ref").append("<div id='" + elementId + "PagePopup' class='refpageimage'></div>"); |
|||
$('#' + elementId + "PagePopup").click(function() { |
|||
$ax.navigate({ |
|||
url: dObj.referencePageUrl, |
|||
target: "new", |
|||
includeVariables: true |
|||
}); |
|||
}); |
|||
} |
|||
}); |
|||
}); |
|||
|
|||
}); |
@ -1,136 +0,0 @@ |
|||
// ******* GLOBAL VARIABLE PROVIDER ******** //
|
|||
$axure.internal(function($ax) { |
|||
var _globalVariableValues = {}; |
|||
|
|||
var _globalVariableProvider = {}; |
|||
$ax.globalVariableProvider = _globalVariableProvider; |
|||
|
|||
var setVariableValue = function(variable, value, suppressBroadcast) { |
|||
if(!(value instanceof Object)) value = value.toString(); |
|||
|
|||
variable = variable.toLowerCase(); |
|||
_globalVariableValues[variable] = value; |
|||
|
|||
if(suppressBroadcast !== true) { |
|||
var varData = { |
|||
globalVarName: variable, |
|||
globalVarValue: value.toString() |
|||
}; |
|||
|
|||
$axure.messageCenter.postMessage('setGlobalVar', varData); |
|||
} |
|||
|
|||
//Post global var values only if pageData is loaded (suppresses exception which occurs when page loads)
|
|||
if($ax.pageData) { |
|||
_postGlobalVarVals(); |
|||
} |
|||
}; |
|||
_globalVariableProvider.setVariableValue = setVariableValue; |
|||
|
|||
var getVariableValue = function(variable, eventInfo, ignoreDefaultsForLinkUrl) { |
|||
variable = variable.toLowerCase(); |
|||
if(_globalVariableValues[variable] !== undefined) { |
|||
//If this is for the GetLinkUrl function and
|
|||
//the current value of the global variable is the same as the default defined in the document, don't return it
|
|||
if(ignoreDefaultsForLinkUrl == true && $ax.document.globalVariables[variable] == _globalVariableValues[variable]) { |
|||
return null; |
|||
} |
|||
|
|||
return _globalVariableValues[variable]; |
|||
} |
|||
if($ax.document.globalVariables[variable] !== undefined) return ignoreDefaultsForLinkUrl == true ? null : $ax.document.globalVariables[variable]; |
|||
switch(variable) { |
|||
case "pagename": return $ax.pageData.page.name; |
|||
|
|||
case "now": return eventInfo.now; |
|||
case "gendate": return $ax.pageData.generationDate; |
|||
|
|||
case "dragx": return $ax.drag.GetDragX(); |
|||
case "dragy": return $ax.drag.GetDragY(); |
|||
case "totaldragx": return $ax.drag.GetTotalDragX(); |
|||
case "totaldragy": return $ax.drag.GetTotalDragY(); |
|||
case "dragtime": return $ax.drag.GetDragTime(); |
|||
|
|||
case "math": return Math; |
|||
case "date": return Date; |
|||
|
|||
case "window": return eventInfo && eventInfo.window; |
|||
case "this": return eventInfo && eventInfo.thiswidget && $ax.getWidgetInfo(eventInfo.thiswidget.elementId); |
|||
case "item": return (eventInfo && eventInfo.item && eventInfo.item.valid && eventInfo.item) || getVariableValue('targetitem', eventInfo, ignoreDefaultsForLinkUrl); |
|||
case "targetitem": return eventInfo && eventInfo.targetElement && $ax.getItemInfo(eventInfo.targetElement); |
|||
case "repeater": return eventInfo && eventInfo.repeater; |
|||
case "target": return eventInfo && eventInfo.targetElement && $ax.getWidgetInfo(eventInfo.targetElement); |
|||
case "cursor": return eventInfo && eventInfo.cursor; |
|||
default: |
|||
var gen = variable.substr(0, 3) == "gen"; |
|||
var date = gen ? $ax.pageData.generationDate : new Date(); |
|||
var prop = gen ? variable.substr(3) : variable; |
|||
switch(prop) { |
|||
case "day": return date.getDate(); |
|||
case "month": return date.getMonth() + 1; |
|||
case "monthname": return $ax.getMonthName(date.getMonth()); |
|||
case "dayofweek": return $ax.getDayOfWeek(date.getDay()); |
|||
case "year": return date.getFullYear(); |
|||
case "time": return date.toLocaleTimeString(); |
|||
case "hours": return date.getHours(); |
|||
case "minutes": return date.getMinutes(); |
|||
case "seconds": return date.getSeconds(); |
|||
default: return ''; |
|||
} |
|||
} |
|||
}; |
|||
_globalVariableProvider.getVariableValue = getVariableValue; |
|||
|
|||
var load = function() { |
|||
let query = (window.location.href.split("#")[1] || ''); //hash.substring(1); Firefox decodes this so & in variables breaks
|
|||
if(query.length > 0) { |
|||
$ax.utils.parseGlobalVars(query, setVariableValue); |
|||
} |
|||
}; |
|||
|
|||
var getLinkUrl = function(baseUrl, useGlobalVarName) { |
|||
var toAdd = ''; |
|||
var definedVariables = _getDefinedVariables(); |
|||
for(var i = 0; i < definedVariables.length; i++) { |
|||
var key = definedVariables[i]; |
|||
var val = getVariableValue(key, undefined, true); |
|||
if(val != null) { |
|||
if(toAdd.length > 0) toAdd += '&'; |
|||
else if(useGlobalVarName) toAdd = GLOBAL_VAR_NAME; |
|||
toAdd += key + '=' + encodeURIComponent(val); |
|||
} |
|||
} |
|||
return toAdd.length > 0 ? baseUrl + (useGlobalVarName ? '' : $axure.shouldSendVarsToServer() ? '?' : '#') + toAdd + "&" + GLOBAL_VAR_CHECKSUM + "=1" : baseUrl; |
|||
}; |
|||
_globalVariableProvider.getLinkUrl = getLinkUrl; |
|||
|
|||
var _getDefinedVariables = function() { |
|||
return $ax.pageData.variables; |
|||
}; |
|||
_globalVariableProvider.getDefinedVariables = _getDefinedVariables; |
|||
|
|||
var _postGlobalVarVals = function() { |
|||
var retVal = {}; |
|||
var definedVariables = _getDefinedVariables(); |
|||
for(var i = 0; i < definedVariables.length; i++) { |
|||
var key = definedVariables[i]; |
|||
var val = getVariableValue(key); |
|||
if(val != null) { |
|||
retVal[key] = val; |
|||
} |
|||
} |
|||
|
|||
$ax.messageCenter.postMessage('globalVariableValues', retVal); |
|||
}; |
|||
|
|||
$ax.messageCenter.addMessageListener(function(message, data) { |
|||
if(message == 'getGlobalVariables') { |
|||
_postGlobalVarVals(); |
|||
} else if(message == 'resetGlobalVariables') { |
|||
_globalVariableValues = {}; |
|||
_postGlobalVarVals(); |
|||
} |
|||
}); |
|||
|
|||
load(); |
|||
}); |
@ -1,268 +0,0 @@ |
|||
// ******* SITEMAP TOOLBAR VIEWER ACTIONS ******** //
|
|||
$axure.internal(function ($ax) { |
|||
var userTriggeredEventNames = ['onClick', 'onDoubleClick', 'onMouseOver', 'onMouseMove', 'onMouseOut', 'onMouseDown', 'onMouseUp', |
|||
'onKeyDown', 'onKeyUp', 'onFocus', 'onLostFocus', 'onTextChange', 'onSelectionChange', 'onSelectedChange', 'onSelect', 'onUnselect', |
|||
'onSwipeLeft', 'onSwipeRight', 'onSwipeUp', 'onSwipeDown', 'onDragStart', 'onDrag', 'onDragDrop', 'onScroll', 'onContextMenu', 'onMouseHover', 'onLongClick']; |
|||
|
|||
//var _toggleSelectWidgetNoteForRepeater = function (repeaterId, scriptId, select) {
|
|||
// var itemIds = $ax.getItemIdsForRepeater(repeaterId);
|
|||
|
|||
// for(var i = 0; i < itemIds.length; i++) {
|
|||
// var itemId = itemIds[i];
|
|||
// var elementId = $ax.repeater.createElementId(scriptId, itemId);
|
|||
// if(select) $('#' + elementId).addClass('widgetNoteSelected');
|
|||
// else $('#' + elementId).removeClass('widgetNoteSelected');
|
|||
// }
|
|||
//}
|
|||
$ax.messageCenter.addMessageListener(function (message, data) { |
|||
//If annotation toggle message received from sitemap, toggle footnotes
|
|||
if(message == 'toggleSelectWidgetNote') { |
|||
|
|||
if (!IOS) { |
|||
$('.widgetNoteSelected').removeClass('widgetNoteSelected'); |
|||
} |
|||
|
|||
if(!data.value) return; |
|||
|
|||
//if(lastSelectedWidgetNote == data.id) {
|
|||
// lastSelectedWidgetNote = null;
|
|||
// return;
|
|||
//}
|
|||
|
|||
$ax('*').each(function(obj, elementId) { |
|||
if (obj.id == data.id) { |
|||
if (!IOS) { |
|||
$('#' + elementId).addClass('widgetNoteSelected'); |
|||
} |
|||
|
|||
_scrollToSelectedNote($('#' + elementId), data.view); |
|||
} |
|||
}); |
|||
} |
|||
}); |
|||
|
|||
var _scrollToSelectedNote = function ($elmt, view) { |
|||
var isLandscape = IOS ? window.orientation != 0 && window.orientation != 180 : false; |
|||
var winWidth = !IOS ? $(window).width() : (isLandscape ? window.screen.height : window.screen.width) - view.panelWidthOffset; |
|||
var winHeight = !IOS ? $(window).height() : view.height; |
|||
var docLeft = $('html').last().scrollLeft(); |
|||
var docTop = $('html').last().scrollTop(); |
|||
var docRight = docLeft + winWidth; |
|||
var docBottom = docTop + winHeight; |
|||
|
|||
var scale = $('#base').css('transform');; |
|||
scale = (scale == "none") ? 1 : Number(scale.substring(scale.indexOf('(') + 1, scale.indexOf(','))); |
|||
|
|||
var bodyLeft = ($('body').css('left') !== undefined && $('body').css('left') !== "auto") ? Number($('body').css('left').replace('px','')) : 0; |
|||
var top = scale * Number($elmt.css('top').replace('px', '')); |
|||
var bottom = top + scale * $elmt.height(); |
|||
var left = scale * Number($elmt.css('left').replace('px', '')) + bodyLeft; |
|||
var right = left + scale * $elmt.width(); |
|||
|
|||
var doHorizontalMove = left < docLeft || right > docRight; |
|||
var doVerticalMove = top < docTop || bottom > docBottom; |
|||
var padding = scale * 50; |
|||
|
|||
var newScrollLeft = 0 |
|||
if (left < docLeft) { |
|||
newScrollLeft = left - padding; |
|||
} else if (right > docRight) { |
|||
newScrollLeft = right + padding - winWidth; |
|||
} |
|||
|
|||
var newScrollTop = 0 |
|||
if (top < docTop) { |
|||
newScrollTop = top - padding; |
|||
} else if (bottom > docBottom) { |
|||
newScrollTop = bottom + padding - winHeight; |
|||
} |
|||
|
|||
// Device Frame or Scale to width or Scale to fit (situations where there is no horizontal scroll)
|
|||
if (view.h || view.scaleVal == 1 || view.scaleVal == 2) { |
|||
doHorizontalMove = false; |
|||
} |
|||
|
|||
// Has Device Frame or Scale to Width and widget with note is outside of viewable panel right bounds
|
|||
if ((view.scaleVal == 1 || view.h) && (left > docRight)) { |
|||
doVerticalMove = false; |
|||
} |
|||
|
|||
// TODO: need to do something for dynamic panel with scroll
|
|||
if (doHorizontalMove && doVerticalMove) { |
|||
$("html, body").animate({ scrollLeft: newScrollLeft, scrollTop: newScrollTop }, 300); |
|||
} else if (doHorizontalMove) { |
|||
$("html, body").animate({ scrollLeft: newScrollLeft }, 300); |
|||
} else if (doVerticalMove) { |
|||
$("html, body").animate({ scrollTop: newScrollTop }, 300); |
|||
} |
|||
} |
|||
|
|||
var highlightEnabled = false; |
|||
$ax.messageCenter.addMessageListener(function(message, data) { |
|||
if(message == 'highlightInteractive') { |
|||
highlightEnabled = data == true; |
|||
_applyHighlight($ax('*')); |
|||
} |
|||
}); |
|||
|
|||
var _applyHighlight = $ax.applyHighlight = function(query, ignoreUnset) { |
|||
if(ignoreUnset && !highlightEnabled) return; |
|||
|
|||
var pulsateClassName = 'legacyPulsateBorder'; |
|||
//Determine if the widget has a defined userTriggeredEventName specified in the array above
|
|||
var _isInteractive = function(diagramObject) { |
|||
if(diagramObject && diagramObject.interactionMap) { |
|||
for(var index in userTriggeredEventNames) { |
|||
if(diagramObject.interactionMap[userTriggeredEventNames[index]]) return true; |
|||
} |
|||
} |
|||
return false; |
|||
}; |
|||
|
|||
//Traverse through parent layers (if any) of an element and see if any have a defined userTriggeredEventName
|
|||
var _findMatchInParent = function(id) { |
|||
var parents = $ax('#' + id).getParents(true, ['layer'])[0]; |
|||
for(var i in parents) { |
|||
var parentId = parents[i]; |
|||
var parentObj = $ax.getObjectFromScriptId(parentId); |
|||
if(_isInteractive(parentObj)) return true; |
|||
} |
|||
return false; |
|||
}; |
|||
|
|||
//Find all widgets with a defined userTriggeredEventName specified in the array above
|
|||
var $matchingElements = query.filter(function (obj, id) { |
|||
|
|||
//This prevents the top left corner of the page from highlighting with everything else
|
|||
if($ax.public.fn.IsLayer(obj.type)) return false; |
|||
|
|||
if(_isInteractive(obj)) return true; |
|||
else if($ax.public.fn.IsVector(obj.type) && obj.referencePageUrl) return true; |
|||
|
|||
//Last check on the object's parent layer(s), if a layer has a defined userTriggeredEventName
|
|||
//then we shall highlight each member of that layer TODO This is a design decision and is subject to change
|
|||
return _findMatchInParent(id); |
|||
}).$(); |
|||
|
|||
var isHighlighted = $matchingElements.is('.' + pulsateClassName); |
|||
|
|||
//Toggle the pulsate class on the matched elements
|
|||
if(highlightEnabled && !isHighlighted) { |
|||
$matchingElements.addClass(pulsateClassName); |
|||
} else if(!highlightEnabled && isHighlighted) { |
|||
$matchingElements.removeClass(pulsateClassName); |
|||
} |
|||
}; |
|||
|
|||
var getElementsFromPoint = function (x, y) { |
|||
var elementsFromPointFn = document.elementsFromPoint || document.msElementsFromPoint; |
|||
if (typeof elementsFromPointFn === "function") { |
|||
return elementsFromPointFn.bind(document)(x, y); |
|||
} |
|||
return []; |
|||
} |
|||
|
|||
$axure.getIdAndRectAtLoc = function (data) { |
|||
var element = document.elementFromPoint(data.x, data.y); |
|||
if (!element) return undefined; |
|||
|
|||
var jObj = _getElementIdFromTarget(element); |
|||
if (jObj.length > 0) { |
|||
var id = jObj.attr('id'); |
|||
var axObj = $ax('#' + id); |
|||
var rect = axObj.pageBoundingRect(); |
|||
return { 'id': id, 'rect': rect }; |
|||
} |
|||
return undefined; |
|||
} |
|||
|
|||
$axure.getListOfIdAndRectAtLoc = function (data) { |
|||
var domElements = getElementsFromPoint(data.x, data.y); |
|||
|
|||
if (!domElements || !domElements.length) return []; |
|||
|
|||
const elements = []; |
|||
|
|||
domElements.forEach(function (domElement) { |
|||
var jObj = _getElementIdFromTarget(domElement); |
|||
if (jObj.length > 0) { |
|||
var id = jObj.attr('id'); |
|||
var axObj = $ax('#' + id); |
|||
var rect = axObj.pageBoundingRect(); |
|||
if (elements.findIndex(function (x) { return x.id === id }) < 0) { |
|||
elements.push( { 'id': id, 'rect': rect } ); |
|||
} |
|||
} |
|||
}); |
|||
|
|||
return elements; |
|||
} |
|||
|
|||
$axure.getIdRectAndStyleAtLoc = function(data) { |
|||
var element = document.elementFromPoint(data.x, data.y); |
|||
if (!element) return undefined; |
|||
|
|||
var jObj = _getElementIdFromTarget(element); |
|||
if (jObj.length > 0) { |
|||
var id = jObj.attr('id'); |
|||
return $axure.getRectAndStyleById(id); |
|||
} |
|||
return undefined; |
|||
} |
|||
|
|||
$axure.getListOfIdRectAndStyleAtLoc = function(data) { |
|||
var domElements = getElementsFromPoint(data.x, data.y); |
|||
|
|||
if (!domElements || !domElements.length) return []; |
|||
|
|||
const elements = []; |
|||
|
|||
domElements.forEach(function (domElement) { |
|||
var jObj = _getElementIdFromTarget(domElement); |
|||
if (jObj.length > 0) { |
|||
var id = jObj.attr('id'); |
|||
if (elements.findIndex(function (x) { return x.id === id }) < 0) { |
|||
elements.push($axure.getRectAndStyleById(id)); |
|||
} |
|||
} |
|||
}); |
|||
|
|||
return elements; |
|||
} |
|||
|
|||
$axure.getRectAndStyleById = function (id) { |
|||
var axObj = $ax('#' + id); |
|||
var rect = axObj.pageBoundingRect(); |
|||
var style = $ax.style.computeFullStyle(id, $ax.style.generateState(id), $ax.adaptive.currentViewId); |
|||
style.text = axObj.text(); |
|||
return { 'id': id, 'rect': rect, 'style': style }; |
|||
} |
|||
|
|||
$axure.isIdVisible = function (id) { |
|||
return id ? $ax.visibility.IsIdVisible(id) : false; |
|||
} |
|||
|
|||
$axure.getParentElementById = function (elementId) { |
|||
if (!elementId) return undefined; |
|||
var parentId = $ax.getLayerParentFromElementId(elementId); |
|||
if (!parentId) { |
|||
return undefined; |
|||
} |
|||
return $axure.getRectAndStyleById(parentId); |
|||
} |
|||
|
|||
var _getElementIdFromTarget = function (target) { |
|||
var targetId = target.id; |
|||
var jTarget = $(target); |
|||
while((!targetId || targetId.indexOf('cache') > -1) && jTarget[0].tagName != 'HTML') { |
|||
jTarget = jTarget.parent(); |
|||
targetId = jTarget.attr('id'); |
|||
} |
|||
if(targetId && targetId != 'base') { |
|||
var sections = targetId.split('_'); |
|||
return $('#' + sections[0]); |
|||
} |
|||
return ''; |
|||
} |
|||
|
|||
}); |
@ -0,0 +1,303 @@ |
|||
let currentPage = 1; |
|||
const rowsPerPage = 10; |
|||
let modelData = []; |
|||
let modelData_bak = []; //用于关键字检索
|
|||
let currentEditingRow = null; |
|||
|
|||
|
|||
|
|||
//页面加载初始化
|
|||
document.addEventListener('DOMContentLoaded', function () { |
|||
fetchModelData(); //初始化通道管理页面元素数据
|
|||
//新增算法模态框---保存按钮
|
|||
document.getElementById('saveButton_model').addEventListener('click',function () { |
|||
addModel(); |
|||
}); |
|||
|
|||
//配置算法模态框--保存按钮
|
|||
document.getElementById('saveButton_config_model').addEventListener('click',function () { |
|||
post_configureModel(); |
|||
}); |
|||
|
|||
//升级算法模态框--保存按钮
|
|||
document.getElementById('saveButton_upmodel').addEventListener('click',function () { |
|||
post_modifyModel(); |
|||
}); |
|||
|
|||
//查询按钮
|
|||
document.getElementById('searchMButton').addEventListener('click',function () { |
|||
searchModel(); |
|||
}); |
|||
}); |
|||
|
|||
//获取算法列表数据,并更新页面
|
|||
async function fetchModelData() { |
|||
try{ |
|||
let response = await fetch('/api/model/list'); |
|||
if (!response.ok) { |
|||
throw new Error('Network response was not ok'); |
|||
} |
|||
modelData = await response.json(); |
|||
modelData_bak = modelData; |
|||
currentPage = 1; // 重置当前页为第一页
|
|||
renderTable(); //刷新表格
|
|||
renderPagination(); |
|||
}catch (error) { |
|||
console.error('Error fetching model data:', error); |
|||
} |
|||
} |
|||
|
|||
//刷新表单页面数据
|
|||
function renderTable() { |
|||
const tableBody = document.getElementById('table-body-model'); |
|||
tableBody.innerHTML = ''; //清空
|
|||
|
|||
const start = (currentPage - 1) * rowsPerPage; |
|||
const end = start + rowsPerPage; |
|||
const pageData = modelData.slice(start, end); |
|||
const surplus_count = rowsPerPage - pageData.length; |
|||
|
|||
|
|||
pageData.forEach((model) => { |
|||
const row = document.createElement('tr'); |
|||
row.innerHTML = ` |
|||
<td>${model.ID}</td> |
|||
<td>${model.name}</td> |
|||
<td>${model.version}</td> |
|||
<td>${model.duration_time}</td> |
|||
<td>${model.proportion}</td> |
|||
<td> |
|||
<button class="btn btn-primary btn-sm modify-btn">升级</button> |
|||
<button class="btn btn-secondary btn-sm algorithm-btn">配置</button> |
|||
<button class="btn btn-danger btn-sm delete-btn">删除</button> |
|||
</td> |
|||
`;
|
|||
tableBody.appendChild(row); |
|||
row.querySelector('.modify-btn').addEventListener('click', () => modifyModel(row)); |
|||
row.querySelector('.algorithm-btn').addEventListener('click', () => configureModel(row)); |
|||
row.querySelector('.delete-btn').addEventListener('click', () => deleteModel(row)); |
|||
}); |
|||
} |
|||
|
|||
//刷新分页标签
|
|||
function renderPagination() { |
|||
const pagination = document.getElementById('pagination-model'); |
|||
pagination.innerHTML = ''; |
|||
|
|||
const totalPages = Math.ceil(modelData.length / rowsPerPage); |
|||
for (let i = 1; i <= totalPages; i++) { |
|||
const pageItem = document.createElement('li'); |
|||
pageItem.className = 'page-item' + (i === currentPage ? ' active' : ''); |
|||
pageItem.innerHTML = `<a class="page-link" href="#">${i}</a>`; |
|||
pageItem.addEventListener('click', (event) => { |
|||
event.preventDefault(); |
|||
currentPage = i; |
|||
renderTable(); |
|||
renderPagination(); |
|||
}); |
|||
pagination.appendChild(pageItem); |
|||
} |
|||
} |
|||
|
|||
//显示升级算法模态框
|
|||
function modifyModel(row){ |
|||
currentEditingRow = row; |
|||
model_name = row.cells[1].innerText; |
|||
version_name = row.cells[2].innerText; |
|||
|
|||
document.getElementById('update_mname_label').innerText = `算法名称: ${model_name}`; |
|||
document.getElementById('update_mversion_label').innerText = `当前版本: ${version_name}`; |
|||
$('#updateMM').modal('show'); |
|||
} |
|||
|
|||
//升级算法模态框--点击保存按钮
|
|||
function post_modifyModel(){ |
|||
mid = currentEditingRow.cells[0].innerText; |
|||
const btn = document.getElementById('saveButton_upmodel'); |
|||
const fileInput = document.getElementById('updateModelFile'); |
|||
const file = fileInput.files[0]; |
|||
if(file){ |
|||
btn.disabled = true; //不可点击
|
|||
const formData = new FormData(); |
|||
formData.append('file', file); |
|||
formData.append('mid', mid); |
|||
|
|||
fetch('/api/model/upgrade', { |
|||
method: 'POST', |
|||
body: formData, |
|||
}) |
|||
.then(response => response.json()) |
|||
.then(data => { |
|||
const istatus = data.status; |
|||
alert(data.msg); |
|||
btn.disabled = false; |
|||
if(istatus == 1 ){ |
|||
fetchModelData(); |
|||
$('#updateMM').modal('hide'); |
|||
} |
|||
}) |
|||
.catch(error => { |
|||
console.error('Error:', error); |
|||
alert('升级失败,请重试。'); |
|||
btn.disabled = false; |
|||
}); |
|||
} |
|||
else{ |
|||
alert('请选择升级包进行上传。'); |
|||
btn.disabled = false; |
|||
} |
|||
} |
|||
|
|||
//显示配置算法模态框
|
|||
function configureModel(row){ |
|||
currentEditingRow = row; |
|||
model_name = row.cells[1].innerText; |
|||
duration_time = row.cells[3].innerText; |
|||
proportion = row.cells[4].innerText; |
|||
//设置模态框控件遍历
|
|||
document.getElementById('config_mname_label').innerText = `算法名称: ${model_name}`; |
|||
document.getElementById('duration_timeInput').value = duration_time; |
|||
document.getElementById('proportionInput').value = proportion; |
|||
$('#configMM').modal('show'); |
|||
} |
|||
|
|||
//配置算法模态框--点击保存按钮
|
|||
function post_configureModel(){ |
|||
mid = currentEditingRow.cells[0].innerText; |
|||
duration_time = parseInt(document.getElementById('duration_timeInput').value); |
|||
proportion = parseFloat(document.getElementById('proportionInput').value); |
|||
if(isNaN(duration_time) || isNaN(proportion) ){ |
|||
alert("请输入数字!"); |
|||
return; |
|||
} |
|||
if(proportion<=0 || proportion>=1){ |
|||
alert("占比阈值需要大于0,且小于1"); |
|||
return; |
|||
} |
|||
//提交数据
|
|||
const url = '/api/model/changecnf'; |
|||
const data = {"mid":mid,"duration_time":duration_time,"proportion":proportion}; |
|||
// 发送 POST 请求
|
|||
fetch(url, { |
|||
method: 'POST', // 指定请求方法为 POST
|
|||
headers: { |
|||
'Content-Type': 'application/json' // 设置请求头,告诉服务器请求体的数据类型为 JSON
|
|||
}, |
|||
body: JSON.stringify(data) // 将 JavaScript 对象转换为 JSON 字符串
|
|||
}) |
|||
.then(response => response.json()) // 将响应解析为 JSON
|
|||
.then(data => { |
|||
const istatus = data.status; |
|||
if(istatus === 0){ |
|||
alert(data.msg); |
|||
return; |
|||
} |
|||
else{ |
|||
//刷新列表
|
|||
fetchModelData(); |
|||
alert(data.msg); |
|||
$('#configMM').modal('hide'); |
|||
} |
|||
}) |
|||
.catch((error) => { |
|||
alert(`Error: ${error.message}`); |
|||
return; |
|||
}); |
|||
} |
|||
|
|||
//删除算法记录
|
|||
function deleteModel(row){ |
|||
if (confirm('确定删除此算法吗?')) { |
|||
mid = row.cells[0].innerText; |
|||
const url = '/api/model/del'; |
|||
const data = {"mid":mid}; |
|||
// 发送 POST 请求
|
|||
fetch(url, { |
|||
method: 'POST', // 指定请求方法为 POST
|
|||
headers: { |
|||
'Content-Type': 'application/json' // 设置请求头,告诉服务器请求体的数据类型为 JSON
|
|||
}, |
|||
body: JSON.stringify(data) // 将 JavaScript 对象转换为 JSON 字符串
|
|||
}) |
|||
.then(response => response.json()) // 将响应解析为 JSON
|
|||
.then(data => { |
|||
const istatus = data.status; |
|||
if(istatus === 0){ |
|||
alert(data.msg); |
|||
return; |
|||
} |
|||
else{ |
|||
//刷新列表
|
|||
row.remove(); |
|||
alert("删除算法成功!"); |
|||
} |
|||
}) |
|||
.catch((error) => { |
|||
alert(`Error: ${error.message}`); |
|||
return; |
|||
}); |
|||
|
|||
} |
|||
} |
|||
|
|||
//新增算法--保存按钮
|
|||
function addModel(){ |
|||
const btn = document.getElementById('saveButton_model'); |
|||
const fileInput = document.getElementById('uploadModelFile'); |
|||
const file = fileInput.files[0]; |
|||
const mName = document.getElementById('MNameInput').value; |
|||
|
|||
if (file && mName) { |
|||
btn.disabled = true; //不可点击
|
|||
const formData = new FormData(); |
|||
formData.append('file', file); |
|||
formData.append('mName', mName); |
|||
|
|||
fetch('/api/model/add', { |
|||
method: 'POST', |
|||
body: formData, |
|||
}) |
|||
.then(response => response.json()) |
|||
.then(data => { |
|||
const istatus = data.status; |
|||
alert(data.msg); |
|||
btn.disabled = false; |
|||
if(istatus == 1 ){ |
|||
fetchModelData(); |
|||
$('#addMM').modal('hide'); |
|||
} |
|||
}) |
|||
.catch(error => { |
|||
console.error('Error:', error); |
|||
alert('上传失败,请重试。'); |
|||
btn.disabled = false; |
|||
}); |
|||
} else { |
|||
alert('请填写算法名称并选择一个升级包进行上传。'); |
|||
btn.disabled = false; |
|||
} |
|||
} |
|||
|
|||
//关键字检索
|
|||
function searchModel(){ |
|||
try { |
|||
const modelName = document.getElementById('modelNameInput').value; |
|||
if(modelName===""){ |
|||
modelData = modelData_bak; |
|||
} |
|||
else{ |
|||
modelData = []; |
|||
modelData_bak.forEach((model) => { |
|||
if(model.name.includes(modelName)){ |
|||
modelData.push(model); |
|||
} |
|||
}); |
|||
} |
|||
// 渲染表格和分页控件
|
|||
currentPage = 1; // 重置当前页为第一页
|
|||
renderTable(); |
|||
renderPagination(); |
|||
} catch (error) { |
|||
console.error('Error performing search:', error); |
|||
} |
|||
} |
@ -1,18 +0,0 @@ |
|||
(function () { |
|||
$.holdReady(true); |
|||
|
|||
var script = window.document.createElement("script"); |
|||
script.type = "text/javascript"; |
|||
script.async = true; |
|||
script.onload = script.onreadystatechange = function (e, isAbort) { |
|||
if (isAbort || !script.readyState || /loaded|complete/.test(script.readyState)) { |
|||
script.onload = script.onreadystatechange = null; |
|||
script = undefined; |
|||
} |
|||
|
|||
if (!isAbort) { $.holdReady(false); } |
|||
} |
|||
|
|||
script.src = "data/document.js"; |
|||
window.document.head.appendChild(script); |
|||
})(); |
@ -1,219 +0,0 @@ |
|||
/* |
|||
* jQuery.splitter.js - two-pane splitter window plugin |
|||
* |
|||
* version 1.51 (2009/01/09) |
|||
* |
|||
* Dual licensed under the MIT and GPL licenses: |
|||
* http://www.opensource.org/licenses/mit-license.php
|
|||
* http://www.gnu.org/licenses/gpl.html
|
|||
*/ |
|||
|
|||
/** |
|||
* The splitter() plugin implements a two-pane resizable splitter window. |
|||
* The selected elements in the jQuery object are converted to a splitter; |
|||
* each selected element should have two child elements, used for the panes |
|||
* of the splitter. The plugin adds a third child element for the splitbar. |
|||
* |
|||
* For more details see: http://methvin.com/splitter/
|
|||
* |
|||
* |
|||
* @example $('#MySplitter').splitter(); |
|||
* @desc Create a vertical splitter with default settings |
|||
* |
|||
* @example $('#MySplitter').splitter({type: 'h', accessKey: 'M'}); |
|||
* @desc Create a horizontal splitter resizable via Alt+Shift+M |
|||
* |
|||
* @name splitter |
|||
* @type jQuery |
|||
* @param Object options Options for the splitter (not required) |
|||
* @cat Plugins/Splitter |
|||
* @return jQuery |
|||
* @author Dave Methvin (dave.methvin@gmail.com) |
|||
*/ |
|||
;(function($){ |
|||
|
|||
$.fn.splitter = function(args){ |
|||
args = args || {}; |
|||
return this.each(function() { |
|||
var zombie; // left-behind splitbar for outline resizes
|
|||
function startSplitMouse(evt) { |
|||
if ( opts.outline ) |
|||
zombie = zombie || bar.clone(false).insertAfter(A); |
|||
panes.css("-webkit-user-select", "none"); // Safari selects A/B text on a move
|
|||
bar.addClass(opts.activeClass); |
|||
$('<div class="splitterMask"></div>').insertAfter(bar); |
|||
A._posSplit = A[0][opts.pxSplit] - evt[opts.eventPos]; |
|||
$(document) |
|||
.bind("mousemove", doSplitMouse) |
|||
.bind("mouseup", endSplitMouse); |
|||
} |
|||
function doSplitMouse(evt) { |
|||
var newPos = A._posSplit+evt[opts.eventPos]; |
|||
if ( opts.outline ) { |
|||
newPos = Math.max(0, Math.min(newPos, splitter._DA - bar._DA)); |
|||
bar.css(opts.origin, newPos); |
|||
} else |
|||
resplit(newPos); |
|||
} |
|||
function endSplitMouse(evt) { |
|||
$('div.splitterMask').remove(); |
|||
bar.removeClass(opts.activeClass); |
|||
var newPos = A._posSplit+evt[opts.eventPos]; |
|||
if ( opts.outline ) { |
|||
zombie.remove(); zombie = null; |
|||
resplit(newPos); |
|||
} |
|||
panes.css("-webkit-user-select", "text"); // let Safari select text again
|
|||
$(document) |
|||
.unbind("mousemove", doSplitMouse) |
|||
.unbind("mouseup", endSplitMouse); |
|||
} |
|||
function resplit(newPos) { |
|||
// Constrain new splitbar position to fit pane size limits
|
|||
newPos = Math.max(A._min, splitter._DA - B._max, |
|||
Math.min(newPos, A._max, splitter._DA - bar._DA - B._min)); |
|||
// Resize/position the two panes
|
|||
bar._DA = bar[0][opts.pxSplit]; // bar size may change during dock
|
|||
|
|||
var posOffset = bar.is(':visible') ? bar._DA - 1 : 0; |
|||
|
|||
bar.css(opts.origin, newPos - posOffset).css(opts.fixed, splitter._DF); |
|||
A.css(opts.origin, 0).css(opts.split, newPos).css(opts.fixed, splitter._DF); |
|||
B.css(opts.origin, newPos + bar._DA - posOffset) |
|||
.css(opts.split, splitter._DA-bar._DA-newPos).css(opts.fixed, splitter._DF); |
|||
// IE fires resize for us; all others pay cash
|
|||
if ( !IE_10_AND_BELOW ) |
|||
panes.trigger("resize"); |
|||
} |
|||
function dimSum(jq, dims) { |
|||
// Opera returns -1 for missing min/max width, turn into 0
|
|||
var sum = 0; |
|||
for ( var i=1; i < arguments.length; i++ ) |
|||
sum += Math.max(parseInt(jq.css(arguments[i])) || 0, 0); |
|||
return sum; |
|||
} |
|||
|
|||
// Determine settings based on incoming opts, element classes, and defaults
|
|||
var vh = (args.splitHorizontal? 'h' : args.splitVertical? 'v' : args.type) || 'v'; |
|||
var opts = $.extend({ |
|||
activeClass: 'active', // class name for active splitter
|
|||
pxPerKey: 8, // splitter px moved per keypress
|
|||
tabIndex: 0, // tab order indicator
|
|||
accessKey: '' // accessKey for splitbar
|
|||
},{ |
|||
v: { // Vertical splitters:
|
|||
keyLeft: 39, keyRight: 37, cursor: "col-resize", |
|||
splitbarClass: "vsplitbar", outlineClass: "voutline", |
|||
type: 'v', eventPos: "pageX", origin: "left", |
|||
split: "width", pxSplit: "offsetWidth", side1: "Left", side2: "Right", |
|||
fixed: "height", pxFixed: "offsetHeight", side3: "Top", side4: "Bottom" |
|||
}, |
|||
h: { // Horizontal splitters:
|
|||
keyTop: 40, keyBottom: 38, cursor: "row-resize", |
|||
splitbarClass: "hsplitbar", outlineClass: "houtline", |
|||
type: 'h', eventPos: "pageY", origin: "top", |
|||
split: "height", pxSplit: "offsetHeight", side1: "Top", side2: "Bottom", |
|||
fixed: "width", pxFixed: "offsetWidth", side3: "Left", side4: "Right" |
|||
} |
|||
}[vh], args); |
|||
|
|||
// Create jQuery object closures for splitter and both panes
|
|||
var splitter = $(this).css({position: "relative"}); |
|||
var panes = $(">*", splitter[0]).css({ |
|||
position: "absolute", // positioned inside splitter container
|
|||
"z-index": "1", // splitbar is positioned above
|
|||
"-moz-outline-style": "none" // don't show dotted outline
|
|||
}); |
|||
var A = $(panes[0]); // left or top
|
|||
var B = $(panes[1]); // right or bottom
|
|||
|
|||
// Focuser element, provides keyboard support; title is shown by Opera accessKeys
|
|||
var focuser = $('<a href="javascript:void(0)"></a>') |
|||
.attr({accessKey: opts.accessKey, tabIndex: opts.tabIndex, title: opts.splitbarClass}) |
|||
//.bind($.browser.opera?"click":"focus", function(){ this.focus(); bar.addClass(opts.activeClass) })
|
|||
.bind("focus", function () { this.focus(); bar.addClass(opts.activeClass) }) |
|||
.bind("keydown", function(e){ |
|||
var key = e.which || e.keyCode; |
|||
var dir = key==opts["key"+opts.side1]? 1 : key==opts["key"+opts.side2]? -1 : 0; |
|||
if ( dir ) |
|||
resplit(A[0][opts.pxSplit]+dir*opts.pxPerKey, false); |
|||
}) |
|||
.bind("blur", function(){ bar.removeClass(opts.activeClass) }); |
|||
|
|||
// Splitbar element, can be already in the doc or we create one
|
|||
var bar = $(panes[2] || '<div></div>') |
|||
.insertAfter(A).css("z-index", "100").append(focuser) |
|||
.attr({"class": opts.splitbarClass, unselectable: "on"}) |
|||
.css({position: "absolute", "user-select": "none", "-webkit-user-select": "none", |
|||
"-khtml-user-select": "none", "-moz-user-select": "none", "top": "0px"}) |
|||
.bind("mousedown", startSplitMouse); |
|||
// Use our cursor unless the style specifies a non-default cursor
|
|||
if ( /^(auto|default|)$/.test(bar.css("cursor")) ) |
|||
bar.css("cursor", opts.cursor); |
|||
|
|||
// Cache several dimensions for speed, rather than re-querying constantly
|
|||
bar._DA = bar[0][opts.pxSplit]; |
|||
splitter._PBF = $.boxModel? dimSum(splitter, "border"+opts.side3+"Width", "border"+opts.side4+"Width") : 0; |
|||
splitter._PBA = $.boxModel? dimSum(splitter, "border"+opts.side1+"Width", "border"+opts.side2+"Width") : 0; |
|||
A._pane = opts.side1; |
|||
B._pane = opts.side2; |
|||
$.each([A,B], function(){ |
|||
this._min = opts["min"+this._pane] || dimSum(this, "min-"+opts.split); |
|||
this._max = opts["max"+this._pane] || dimSum(this, "max-"+opts.split) || 9999; |
|||
this._init = opts["size"+this._pane]===true ? |
|||
parseInt($.curCSS(this[0],opts.split)) : opts["size"+this._pane]; |
|||
}); |
|||
|
|||
// Determine initial position, get from cookie if specified
|
|||
var initPos = A._init; |
|||
if ( !isNaN(B._init) ) // recalc initial B size as an offset from the top or left side
|
|||
initPos = splitter[0][opts.pxSplit] - splitter._PBA - B._init - bar._DA; |
|||
if ( opts.cookie ) { |
|||
if ( !$.cookie ) |
|||
alert('jQuery.splitter(): jQuery cookie plugin required'); |
|||
var ckpos = parseInt($.cookie(opts.cookie)); |
|||
if ( !isNaN(ckpos) ) |
|||
initPos = ckpos; |
|||
$(window).bind("unload", function(){ |
|||
var state = String(bar.css(opts.origin)); // current location of splitbar
|
|||
$.cookie(opts.cookie, state, {expires: opts.cookieExpires || 365, |
|||
path: opts.cookiePath || document.location.pathname}); |
|||
}); |
|||
} |
|||
if ( isNaN(initPos) ) // King Solomon's algorithm
|
|||
initPos = Math.round((splitter[0][opts.pxSplit] - splitter._PBA - bar._DA)/2); |
|||
|
|||
// Resize event propagation and splitter sizing
|
|||
if ( opts.anchorToWindow ) { |
|||
// Account for margin or border on the splitter container and enforce min height
|
|||
splitter._hadjust = dimSum(splitter, "borderTopWidth", "borderBottomWidth", "marginBottom"); |
|||
splitter._hmin = Math.max(dimSum(splitter, "minHeight"), 20); |
|||
$(window).bind("resize", function(){ |
|||
var top = splitter.offset().top; |
|||
var wh = $(window).height(); |
|||
splitter.css("height", Math.max(wh-top-splitter._hadjust, splitter._hmin)+"px"); |
|||
if ( !IE_10_AND_BELOW ) splitter.trigger("resize"); |
|||
}).trigger("resize"); |
|||
} |
|||
else if ( opts.resizeToWidth && !IE_10_AND_BELOW ) |
|||
$(window).bind("resize", function(){ |
|||
splitter.trigger("resize"); |
|||
}); |
|||
|
|||
// Resize event handler; triggered immediately to set initial position
|
|||
splitter.bind("resize", function(e, size){ |
|||
// Custom events bubble in jQuery 1.3; don't Yo Dawg
|
|||
if ( e.target != this ) return; |
|||
// Determine new width/height of splitter container
|
|||
splitter._DF = splitter[0][opts.pxFixed] - splitter._PBF; |
|||
splitter._DA = splitter[0][opts.pxSplit] - splitter._PBA; |
|||
// Bail if splitter isn't visible or content isn't there yet
|
|||
if ( splitter._DF <= 0 || splitter._DA <= 0 ) return; |
|||
// Re-divvy the adjustable dimension; maintain size of the preferred pane
|
|||
resplit(!isNaN(size)? size : (!(opts.sizeRight||opts.sizeBottom)? A[0][opts.pxSplit] : |
|||
splitter._DA-B[0][opts.pxSplit]-bar._DA)); |
|||
}).trigger("resize" , [initPos]); |
|||
}); |
|||
}; |
|||
|
|||
})(jQuery); |
@ -0,0 +1,440 @@ |
|||
let currentPage = 1; |
|||
const rowsPerPage = 10; |
|||
let currentEditingRow = null; |
|||
let areaData = []; |
|||
let areaData_bak = []; |
|||
//网络信息
|
|||
let wired_type; |
|||
let wired_ip; |
|||
let wired_mask; |
|||
let wired_gateway; |
|||
let wired_dns; |
|||
let wireless_type; |
|||
let wireless_ip; |
|||
let wireless_mask; |
|||
let wireless_gateway; |
|||
let wireless_dns; |
|||
let wireless_ssid; |
|||
let wireless_passwd; |
|||
let wifi_list = []; |
|||
|
|||
//页面加载初始化
|
|||
document.addEventListener('DOMContentLoaded', function () { |
|||
fetchSystemData(); //初始化系统信息
|
|||
fetchAreaData();//初始化区域信息
|
|||
//升级按钮
|
|||
document.getElementById('upsystem').addEventListener('click',function () {upgrade_system();}); |
|||
|
|||
//设备IP配置按钮--显示模态框
|
|||
document.getElementById('showIPConfig').addEventListener('click',function () {show_IPConfigModel();}); |
|||
//设备IP配置模态框--保存按钮
|
|||
document.getElementById('saveIPConfig').addEventListener('click',function () {save_IPConfig();}); |
|||
document.getElementById('connectWifi').addEventListener('click',function () {connect_wifi();}); |
|||
|
|||
//服务器IP配置
|
|||
document.getElementById('showServerIP').addEventListener('click',function () {show_ServerIPConfig();}); |
|||
document.getElementById('saveServerIP').addEventListener('click',function () {save_ServerIPConfig();}); |
|||
|
|||
//区域管理
|
|||
document.getElementById('addAreaButton').addEventListener('click',function () {show_AreaManager();}); |
|||
document.getElementById('addArea').addEventListener('click',function () {add_Area();}); |
|||
|
|||
//修改区域模态框
|
|||
document.getElementById('modifArea').addEventListener('click',function () {modify_Area();}); |
|||
}); |
|||
|
|||
//刷新系统信息
|
|||
async function fetchSystemData() { |
|||
try{ |
|||
let response = await fetch('/api/system/info'); |
|||
if (!response.ok) { |
|||
throw new Error('Network response was not ok'); |
|||
} |
|||
data = await response.json(); |
|||
|
|||
document.getElementById('system_version').textContent = data.version; |
|||
document.getElementById('dev_ID').textContent = data.ID; |
|||
document.getElementById('service_ip').value = data.service_ip; |
|||
document.getElementById('service_port').value = data.service_port; |
|||
//网络信息
|
|||
wired_type = data.wired_type; |
|||
wired_ip = data.wired_ip; |
|||
wired_mask = data.wired_mask; |
|||
wired_gateway = data.wired_gateway; |
|||
wired_dns = data.wired_dns; |
|||
wireless_type = data.wireless_type; |
|||
wireless_ip = data.wireless_ip; |
|||
wireless_mask = data.wireless_mask; |
|||
wireless_gateway = data.wireless_gateway; |
|||
wireless_dns = data.wireless_dns; |
|||
wireless_ssid = data.ssid; |
|||
wireless_passwd = data.wifi_passwd; |
|||
//wifi -list
|
|||
wifi_list = data.wifi_list; |
|||
wifi_list.unshift("请选择"); |
|||
document.getElementById('dev_IP').textContent = `有线--${wired_ip} 无线--${wireless_ip}`; |
|||
|
|||
|
|||
}catch (error) { |
|||
console.error('Error fetching model data:', error); |
|||
} |
|||
} |
|||
|
|||
//刷新区域信息--
|
|||
async function fetchAreaData() { |
|||
try{ |
|||
let response = await fetch('/api/system/area'); |
|||
if (!response.ok) { |
|||
throw new Error('Network response was not ok'); |
|||
} |
|||
areaData = await response.json(); |
|||
areaData_bak = areaData; |
|||
currentPage = 1; // 重置当前页为第一页
|
|||
renderTable(); //刷新表格
|
|||
renderPagination(); |
|||
}catch (error) { |
|||
console.error('Error fetching model data:', error); |
|||
} |
|||
} |
|||
|
|||
//刷新表格
|
|||
function renderTable(){ |
|||
const tableBody = document.getElementById('table-body-area'); |
|||
tableBody.innerHTML = ''; |
|||
|
|||
const start = (currentPage - 1) * rowsPerPage; |
|||
const end = start + rowsPerPage; |
|||
const pageData = areaData.slice(start, end); |
|||
const surplus_count = rowsPerPage - pageData.length; |
|||
|
|||
pageData.forEach((area) => { |
|||
const row = document.createElement('tr'); |
|||
row.innerHTML = ` |
|||
<td>${area.ID}</td> |
|||
<td>${area.area_name}</td> |
|||
<td> |
|||
<button class="btn btn-primary btn-sm modify-btn">修改</button> |
|||
<button class="btn btn-danger btn-sm delete-btn">删除</button> |
|||
</td> |
|||
`;
|
|||
tableBody.appendChild(row); |
|||
row.querySelector('.modify-btn').addEventListener('click', () => show_modify_Area(row)); |
|||
row.querySelector('.delete-btn').addEventListener('click', () => del_Area(row)); |
|||
}); |
|||
} |
|||
|
|||
//刷新分页标签
|
|||
function renderPagination() { |
|||
const pagination = document.getElementById('pagination-area'); |
|||
pagination.innerHTML = ''; |
|||
|
|||
const totalPages = Math.ceil(areaData.length / rowsPerPage); |
|||
for (let i = 1; i <= totalPages; i++) { |
|||
const pageItem = document.createElement('li'); |
|||
pageItem.className = 'page-item' + (i === currentPage ? ' active' : ''); |
|||
pageItem.innerHTML = `<a class="page-link" href="#">${i}</a>`; |
|||
pageItem.addEventListener('click', (event) => { |
|||
event.preventDefault(); |
|||
currentPage = i; |
|||
renderTable(); |
|||
renderPagination(); |
|||
}); |
|||
pagination.appendChild(pageItem); |
|||
} |
|||
} |
|||
|
|||
//系统升级
|
|||
async function upgrade_system(){ |
|||
alert("点击了系统升级按钮"); |
|||
} |
|||
|
|||
//设备IP地址配置 --- 显示模态框---------------------
|
|||
function show_IPConfigModel(){ |
|||
//wired页面
|
|||
const el_wired_dhcp = document.getElementById('dhcp_lan'); |
|||
const el_wired_static = document.getElementById('static_lan'); |
|||
const el_wired_ip = document.getElementById('wiredIpAddress'); |
|||
const el_wired_mask = document.getElementById('wiredSubnetMask'); |
|||
const el_wired_gateway = document.getElementById('wiredGateway'); |
|||
const el_wired_dns = document.getElementById('wiredDNS'); |
|||
if(wired_type==0){ //dhcp
|
|||
el_wired_dhcp.checked = true; |
|||
}else{ |
|||
el_wired_static.checked = true; |
|||
} |
|||
el_wired_ip.value = wired_ip; |
|||
el_wired_mask.value = wired_mask; |
|||
el_wired_gateway.value = wired_gateway; |
|||
el_wired_dns.value = wired_dns; |
|||
|
|||
//wireless页面
|
|||
//document.getElementById('wirelessNetwork');
|
|||
|
|||
const el_wireless_passwd = document.getElementById('wifi_passwd'); |
|||
const el_wireless_dhcp = document.getElementById('dhcp_wifi'); |
|||
const el_wireless_static = document.getElementById('static_wifi'); |
|||
const el_wireless_ip = document.getElementById('wirelessIpAddress'); |
|||
const el_wireless_mask = document.getElementById('wirelessSubnetMask'); |
|||
const el_wireless_gateway = document.getElementById('wirelessGateway'); |
|||
const el_wireless_dns = document.getElementById('wirelessDNS'); |
|||
|
|||
//wireless_ssid = data.ssid;
|
|||
//wireless_passwd = data.wifi_passwd;
|
|||
if(wired_type==0){ //dhcp
|
|||
el_wireless_dhcp.checked = true; |
|||
}else{ |
|||
el_wireless_static.checked = true; |
|||
} |
|||
set_select_data("wirelessNetwork",wifi_list); |
|||
if(wireless_ssid == null || wireless_ssid == ""){ |
|||
//控件不可操作
|
|||
el_wireless_dhcp.disabled=true; |
|||
el_wireless_static.disabled=true; |
|||
el_wireless_ip.disabled=true; |
|||
el_wireless_mask.disabled=true; |
|||
el_wireless_gateway.disabled=true; |
|||
el_wireless_dns.disabled=true; |
|||
}else{ |
|||
let bfind = set_select_selct("wirelessNetwork",wireless_ssid); |
|||
if(bfind== false){ |
|||
el_wireless_dhcp.disabled=true; |
|||
el_wireless_static.disabled=true; |
|||
el_wireless_ip.disabled=true; |
|||
el_wireless_mask.disabled=true; |
|||
el_wireless_gateway.disabled=true; |
|||
el_wireless_dns.disabled=true; |
|||
}else{ |
|||
el_wireless_passwd.value = wireless_passwd; |
|||
el_wireless_ip.value = wireless_ip; |
|||
el_wireless_mask.value = wireless_mask; |
|||
el_wireless_gateway.value = wireless_gateway; |
|||
el_wireless_dns.value = wireless_dns; |
|||
} |
|||
} |
|||
$('#ipConfigModal').modal('show'); |
|||
} |
|||
//点击连接wifi 按钮
|
|||
async function connect_wifi(){ |
|||
alert("点击了连接wifi按钮"); |
|||
} |
|||
|
|||
//设备IP地址配置 --- 点击保存按钮
|
|||
async function save_IPConfig(){ |
|||
alert("点击了设备IP保存按钮"); |
|||
} |
|||
|
|||
//IP配置模态框,单选按钮点击
|
|||
function handleRadioClick_lan(event){ |
|||
const selectedRadio = event.target; |
|||
const el_ip = document.getElementById('wiredIpAddress'); |
|||
const el_mask = document.getElementById('wiredSubnetMask'); |
|||
const el_gateway = document.getElementById('wiredGateway'); |
|||
const el_dns = document.getElementById('wiredDNS'); |
|||
let net_type = 0; //0--dhcp,1--static
|
|||
if (selectedRadio.id === 'dhcp_lan') { |
|||
net_type = 1; |
|||
el_ip.disabled = true; |
|||
el_mask.disabled = true; |
|||
el_gateway.disabled = true; |
|||
el_dns.disabled = true; |
|||
} |
|||
else if(selectedRadio.id === 'static_lan'){ |
|||
net_type = 2; |
|||
el_ip.disabled = false; |
|||
el_mask.disabled = false; |
|||
el_gateway.disabled = false; |
|||
el_dns.disabled = false; |
|||
} |
|||
} |
|||
|
|||
//IP配置模态框,单选按钮点击
|
|||
function handleRadioClick_wifi(event){ |
|||
const selectedRadio = event.target; |
|||
let wifi_type = 0; //0--dhcp,1--static
|
|||
const el_ip = document.getElementById('wirelessIpAddress'); |
|||
const el_mask = document.getElementById('wirelessSubnetMask'); |
|||
const el_gateway = document.getElementById('wirelessGateway'); |
|||
const el_dns = document.getElementById('wirelessDNS'); |
|||
if (selectedRadio.id === 'dhcp_wifi') { |
|||
net_type = 1; |
|||
el_ip.disabled = true; |
|||
el_mask.disabled = true; |
|||
el_gateway.disabled = true; |
|||
el_dns.disabled = true; |
|||
} |
|||
else if(selectedRadio.id === 'static_wifi'){ |
|||
net_type = 2; |
|||
el_ip.disabled = false; |
|||
el_mask.disabled = false; |
|||
el_gateway.disabled = false; |
|||
el_dns.disabled = false; |
|||
} |
|||
|
|||
} |
|||
|
|||
//服务器IP配置-----------------------------------------
|
|||
function show_ServerIPConfig(){ |
|||
const el_serviceIP = document.getElementById('serviceIP_model'); |
|||
const el_servicePort = document.getElementById('servicePort_model'); |
|||
el_serviceIP.value = document.getElementById('service_ip').value; |
|||
el_servicePort.value = document.getElementById('service_port').value; |
|||
$('#ServerIPModal').modal('show'); |
|||
} |
|||
|
|||
async function save_ServerIPConfig(){ |
|||
const el_serverIP = document.getElementById('serviceIP_model'); |
|||
const el_serverPort = document.getElementById('servicePort_model'); |
|||
const btn = document.getElementById('saveServerIP'); |
|||
serverIP = el_serverIP.value; |
|||
serverPort = el_serverPort.value; |
|||
if(serverIP==="" || serverPort===""){ |
|||
alert("服务端IP和端口号不能为空!") |
|||
} |
|||
else{ |
|||
if(isValidIP(serverIP)){ |
|||
btn.disabled = true; |
|||
const formData = new FormData(); |
|||
formData.append('ip', serverIP); |
|||
formData.append('port', serverPort); |
|||
fetch("/api/system/changeserver", { |
|||
method: 'POST', |
|||
body: formData, |
|||
}) |
|||
.then(response => response.json()) |
|||
.then(data => { |
|||
btn.disabled = false; |
|||
const istatus = data.status; |
|||
alert(data.msg); |
|||
if(istatus == 1){ |
|||
fetchSystemData(); |
|||
$('#ServerIPModal').modal('hide'); |
|||
} |
|||
}) |
|||
.catch(error => { |
|||
console.error('Error:', error); |
|||
alert('修改失败,请重试。'); |
|||
btn.disabled = false; |
|||
}); |
|||
} |
|||
else{ |
|||
alert("请输入正确的IP地址!") |
|||
} |
|||
} |
|||
} |
|||
|
|||
//区域管理-------------------------------------------
|
|||
function show_AreaManager(){ |
|||
$('#addAreaModal').modal('show'); |
|||
} |
|||
|
|||
async function add_Area(){ |
|||
const el_ereaname = document.getElementById('area_name'); |
|||
const btn = document.getElementById('addArea'); |
|||
area_name = el_ereaname.value; |
|||
if(area_name===""){ |
|||
alert("请输入区域名称"); |
|||
}else{ |
|||
btn.disabled = true; |
|||
//提交数据
|
|||
const url = '/api/channel/area/add'; |
|||
const data = {"name":area_name}; |
|||
// 发送 POST 请求
|
|||
fetch(url, { |
|||
method: 'POST', // 指定请求方法为 POST
|
|||
headers: { |
|||
'Content-Type': 'application/json' // 设置请求头,告诉服务器请求体的数据类型为 JSON
|
|||
}, |
|||
body: JSON.stringify(data) // 将 JavaScript 对象转换为 JSON 字符串
|
|||
}) |
|||
.then(response => response.json()) // 将响应解析为 JSON
|
|||
.then(data => { |
|||
btn.disabled = false; |
|||
const istatus = data.status; |
|||
alert(data.msg); |
|||
if(istatus == 1){ |
|||
fetchAreaData(); |
|||
$('#addAreaModal').modal('hide'); |
|||
} |
|||
}) |
|||
.catch((error) => { |
|||
alert(`Error: ${error.message}`); |
|||
btn.disabled = false; |
|||
}); |
|||
} |
|||
} |
|||
|
|||
//显示修改区域信息
|
|||
function show_modify_Area(row){ |
|||
currentEditingRow = row; |
|||
area_name = row.cells[1].innerText; |
|||
const el_areaname = document.getElementById('area_name_modif'); |
|||
el_areaname.value = area_name; |
|||
$('#modifyAreaModal').modal('show'); |
|||
} |
|||
|
|||
//点击修改模态框的保存按钮
|
|||
async function modify_Area(){ |
|||
area_id = currentEditingRow.cells[0].innerText; |
|||
area_name = document.getElementById('area_name_modif').value; |
|||
const btn = document.getElementById('modifArea'); |
|||
if(area_name===""){ |
|||
alert("请输入区域名称!") |
|||
}else{ |
|||
btn.disabled = true; |
|||
//提交数据
|
|||
const url = '/api/channel/area/change'; |
|||
const formData = new FormData(); |
|||
formData.append('name', area_name); |
|||
formData.append('id', area_id); |
|||
//const data = {"name":area_name,"id":area_id};
|
|||
// 发送 POST 请求
|
|||
fetch(url, { |
|||
method: 'POST', |
|||
body: formData, |
|||
}) |
|||
.then(response => response.json()) // 将响应解析为 JSON
|
|||
.then(data => { |
|||
btn.disabled = false; |
|||
const istatus = data.status; |
|||
alert(data.msg); |
|||
if(istatus == 1){ |
|||
fetchAreaData(); |
|||
$('#modifyAreaModal').modal('hide'); |
|||
} |
|||
}) |
|||
.catch((error) => { |
|||
alert(`Error: ${error.message}`); |
|||
btn.disabled = false; |
|||
}); |
|||
} |
|||
} |
|||
|
|||
//删除区域信息
|
|||
async function del_Area(row){ |
|||
if (confirm('确定删除此区域吗?')){ |
|||
currentEditingRow = row; |
|||
area_id =row.cells[0].innerText; |
|||
const url = '/api/channel/area/del'; |
|||
const formData = new FormData(); |
|||
formData.append('id', area_id); |
|||
//const data = {"name":area_name,"id":area_id};
|
|||
// 发送 POST 请求
|
|||
fetch(url, { |
|||
method: 'POST', |
|||
body: formData, |
|||
}) |
|||
.then(response => response.json()) // 将响应解析为 JSON
|
|||
.then(data => { |
|||
const istatus = data.status; |
|||
alert(data.msg); |
|||
if(istatus == 1){ |
|||
//刷新列表
|
|||
row.remove(); |
|||
} |
|||
}) |
|||
.catch((error) => { |
|||
alert(`Error: ${error.message}`); |
|||
btn.disabled = false; |
|||
}); |
|||
} |
|||
} |
@ -0,0 +1,48 @@ |
|||
document.getElementById('changePasswd').addEventListener('click',function () { |
|||
changePasswd(); |
|||
}); |
|||
|
|||
function changePasswd(){ |
|||
const el_oldpasswd = document.getElementById('source_passwd'); |
|||
const el_new_passwd = document.getElementById('new_passwd'); |
|||
const el_again_passwd = document.getElementById('again_passwd'); |
|||
const btn = document.getElementById('changePasswd'); |
|||
oldpasswd = el_oldpasswd.value; |
|||
newpasswd = el_new_passwd.value; |
|||
againpasswd = el_again_passwd.value; |
|||
if(oldpasswd === "" || newpasswd === "" || againpasswd === ""){ |
|||
alert("密码不能为空!") |
|||
}else{ |
|||
if(newpasswd !== againpasswd){ |
|||
alert("两次输入的密码不相同!") |
|||
}else{ |
|||
btn.disabled = true; |
|||
//提交请求
|
|||
const url = "/api/user/passwd" |
|||
const data = {"oldpasswd":oldpasswd,"newpasswd":newpasswd}; |
|||
fetch(url, { |
|||
method: 'POST', // 指定请求方法为 POST
|
|||
headers: { |
|||
'Content-Type': 'application/json' // 设置请求头,告诉服务器请求体的数据类型为 JSON
|
|||
}, |
|||
body: JSON.stringify(data) // 将 JavaScript 对象转换为 JSON 字符串
|
|||
}) |
|||
.then(response => response.json()) // 将响应解析为 JSON
|
|||
.then(data => { |
|||
btn.disabled = false; |
|||
const istatus = data.status; |
|||
alert(data.msg); |
|||
if(istatus == 1){ |
|||
el_oldpasswd.value = ""; |
|||
el_new_passwd.value = ""; |
|||
el_again_passwd.value = ""; |
|||
} |
|||
}) |
|||
.catch((error) => { |
|||
btn.disabled = false; |
|||
alert(`Error: ${error.message}`); |
|||
return; |
|||
}); |
|||
} |
|||
} |
|||
} |
@ -0,0 +1,145 @@ |
|||
{% extends 'base.html' %} |
|||
|
|||
{% block title %}ZFBOX{% endblock %} |
|||
|
|||
{% block style %} |
|||
.table-container { |
|||
min-height: 400px; /* 设置最小高度,可以根据需要调整 */ |
|||
} |
|||
/* 缩小表格行高 */ |
|||
.table-sm th, |
|||
.table-sm td { |
|||
padding: 0.2rem; /* 调整这里的值来改变行高 */ |
|||
} |
|||
.pagination { |
|||
justify-content: flex-end; /* 右对齐 */ |
|||
} |
|||
|
|||
{% endblock %} |
|||
|
|||
{% block content %} |
|||
<div class="container d-flex flex-column" > |
|||
<!-- 模态框区域 --> |
|||
<!-- 新增算法模态框 --> |
|||
<div class="modal fade" id="addMM" data-bs-backdrop="static" data-bs-keyboard="false" tabindex="-1" aria-labelledby="add_model" aria-hidden="true"> |
|||
<div class="modal-dialog"> |
|||
<div class="modal-content"> |
|||
<div class="modal-header"> |
|||
<h5 class="modal-title">新增算法</h5> |
|||
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button> |
|||
</div> |
|||
<div class="modal-body"> |
|||
<div class="form-group mb-2"> |
|||
<label for="MNameInput" class="form-label">算法名称:</label> |
|||
<input type="text" class="form-control" id="MNameInput"> |
|||
</div> |
|||
<div class="form-group mb-2"> |
|||
<label for="uploadModelFile" class="form-label">上传文件:</label> |
|||
<input type="file" class="form-control" id="uploadModelFile" accept=".zip"> |
|||
</div> |
|||
</div> |
|||
<div class="modal-footer"> |
|||
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal" id="cancelButton_model">取消</button> |
|||
<button type="button" class="btn btn-primary" id="saveButton_model">保存</button> |
|||
</div> |
|||
</div> |
|||
</div> |
|||
</div> |
|||
<!-- 升级算法模态框 --> |
|||
<div class="modal fade" id="updateMM" data-bs-backdrop="static" data-bs-keyboard="false" tabindex="-1" aria-labelledby="update_model" aria-hidden="true"> |
|||
<div class="modal-dialog"> |
|||
<div class="modal-content"> |
|||
<div class="modal-header"> |
|||
<h5 class="modal-title">升级算法</h5> |
|||
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button> |
|||
</div> |
|||
<div class="modal-body"> |
|||
<div class="form-group mb-3"> |
|||
<label id="update_mname_label" class="form-label">算法名称:</label> |
|||
</div> |
|||
<div class="form-group mb-3"> |
|||
<label id="update_mversion_label" class="form-label">当前版本:</label> |
|||
</div> |
|||
<div class="form-group mb-3"> |
|||
<label for="uploadModelFile" class="form-label">上传文件:</label> |
|||
<input type="file" class="form-control" id="updateModelFile" accept=".zip"> |
|||
</div> |
|||
</div> |
|||
<div class="modal-footer"> |
|||
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal" id="cancelButton_upmodel">取消</button> |
|||
<button type="button" class="btn btn-primary" id="saveButton_upmodel">保存</button> |
|||
</div> |
|||
</div> |
|||
</div> |
|||
</div> |
|||
<!-- 配置算法模态框 --> |
|||
<div class="modal fade" id="configMM" data-bs-backdrop="static" data-bs-keyboard="false" tabindex="-1" aria-labelledby="config_model" aria-hidden="true"> |
|||
<div class="modal-dialog"> |
|||
<div class="modal-content"> |
|||
<div class="modal-header"> |
|||
<h5 class="modal-title">配置算法</h5> |
|||
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button> |
|||
</div> |
|||
<div class="modal-body"> |
|||
<div class="form-group mb-3"> |
|||
<label id="config_mname_label" class="form-label">算法名称:</label> |
|||
</div> |
|||
<div class="form-group mb-3"> |
|||
<label for="duration_timeInput" class="form-label">持续判断时间(秒):</label> |
|||
<input type="text" class="form-control" id="duration_timeInput"> |
|||
</div> |
|||
<div class="form-group mb-3"> |
|||
<label for="proportionInput" class="form-label">占比阈值(0-1):</label> |
|||
<input type="text" class="form-control" id="proportionInput"> |
|||
</div> |
|||
</div> |
|||
<div class="modal-footer"> |
|||
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal" id="cancelButton_config_model">取消</button> |
|||
<button type="button" class="btn btn-primary" id="saveButton_config_model">保存</button> |
|||
</div> |
|||
</div> |
|||
</div> |
|||
</div> |
|||
<!-- 搜索区 --> |
|||
<div class="row justify-content-center align-items-center mb-3"> |
|||
<div class="col-md-2 text-end"><label class="col-form-label form-label">算法名称:</label></div> |
|||
<div class="col-md-6"><input id="modelNameInput" type="text" class="form-control"></div> |
|||
<div class="col-md-2"><button id="searchMButton" type="button" class="btn btn-primary">查 询</button></div> |
|||
</div> |
|||
<!-- 按钮区 --> |
|||
<div class="mb-3"> |
|||
<button id="addModelButton" type="button" class="btn btn-primary" data-bs-toggle="modal" data-bs-target="#addMM"> |
|||
新增算法 |
|||
</button> |
|||
</div> |
|||
<!-- 表格区 --> |
|||
<div class="table-container"> |
|||
<table class="table"> |
|||
<thead class="table-light"> |
|||
<tr> |
|||
<th scope="col">ID</th> |
|||
<th scope="col">算法名称</th> |
|||
<th scope="col">版本号</th> |
|||
<th scope="col">持续判断时间</th> |
|||
<th scope="col">占比阈值</th> |
|||
<th scope="col">操作</th> |
|||
</tr> |
|||
</thead> |
|||
<tbody id="table-body-model" class="table-group-divider"> |
|||
<!-- 表格数据动态填充 --> |
|||
</tbody> |
|||
</table> |
|||
<nav> |
|||
<ul id="pagination-model" class="pagination"> |
|||
<!-- 分页控件将动态生成 --> |
|||
</ul> |
|||
</nav> |
|||
</div> |
|||
|
|||
</div> |
|||
{% endblock %} |
|||
|
|||
{% block script %} |
|||
<script src="{{ url_for('main.static', filename='scripts/model_manager.js') }}"></script> |
|||
<script src="{{ url_for('main.static', filename='scripts/jquery-3.2.1.slim.min.js') }}"></script> |
|||
{% endblock %} |
@ -1,156 +0,0 @@ |
|||
<!DOCTYPE html> |
|||
<html lang="en"> |
|||
<head> |
|||
<meta charset="UTF-8"> |
|||
<meta name="viewport" content="width=device-width, initial-scale=1.0"> |
|||
<title>布防时间计划</title> |
|||
<link rel="stylesheet" href="{{ url_for('main.static', filename='css/bootstrap.min.css') }}"> |
|||
<style> |
|||
.schedule-table { |
|||
width: 100%; |
|||
table-layout: fixed; |
|||
} |
|||
.schedule-table th, .schedule-table td { |
|||
text-align: center; |
|||
vertical-align: middle; |
|||
cursor: pointer; |
|||
border: 1px solid #dee2e6; |
|||
padding: 8px; |
|||
} |
|||
.schedule-table td.allowed { |
|||
background-color: white; |
|||
} |
|||
.schedule-table td.blocked { |
|||
background-color: blue; |
|||
} |
|||
</style> |
|||
</head> |
|||
<body> |
|||
<div class="container mt-5"> |
|||
<table class="schedule-table table table-bordered"> |
|||
<thead> |
|||
<tr> |
|||
<th>小时</th> |
|||
<th>00</th> |
|||
<th>01</th> |
|||
<th>02</th> |
|||
<th>03</th> |
|||
<th>04</th> |
|||
<th>05</th> |
|||
<th>06</th> |
|||
<th>07</th> |
|||
<th>08</th> |
|||
<th>09</th> |
|||
<th>10</th> |
|||
<th>11</th> |
|||
<th>12</th> |
|||
<th>13</th> |
|||
<th>14</th> |
|||
<th>15</th> |
|||
<th>16</th> |
|||
<th>17</th> |
|||
<th>18</th> |
|||
<th>19</th> |
|||
<th>20</th> |
|||
<th>21</th> |
|||
<th>22</th> |
|||
<th>23</th> |
|||
</tr> |
|||
</thead> |
|||
<tbody> |
|||
<!-- Repeat above row for each day of the week (Monday to Saturday) --> |
|||
<tr> |
|||
<th>星期一</th> |
|||
<td class="blocked"></td><td class="blocked"></td><td class="blocked"></td><td class="blocked"></td> |
|||
<td class="blocked"></td><td class="blocked"></td><td class="blocked"></td><td class="blocked"></td> |
|||
<td class="blocked"></td><td class="blocked"></td><td class="blocked"></td><td class="blocked"></td> |
|||
<td class="blocked"></td><td class="blocked"></td><td class="blocked"></td><td class="blocked"></td> |
|||
<td class="blocked"></td><td class="blocked"></td><td class="blocked"></td><td class="blocked"></td> |
|||
<td class="blocked"></td><td class="blocked"></td><td class="blocked"></td><td class="blocked"></td> |
|||
</tr> |
|||
<tr> |
|||
<th>星期二</th> |
|||
<td class="blocked"></td><td class="blocked"></td><td class="blocked"></td><td class="blocked"></td> |
|||
<td class="blocked"></td><td class="blocked"></td><td class="blocked"></td><td class="blocked"></td> |
|||
<td class="blocked"></td><td class="blocked"></td><td class="blocked"></td><td class="blocked"></td> |
|||
<td class="blocked"></td><td class="blocked"></td><td class="blocked"></td><td class="blocked"></td> |
|||
<td class="blocked"></td><td class="blocked"></td><td class="blocked"></td><td class="blocked"></td> |
|||
<td class="blocked"></td><td class="blocked"></td><td class="blocked"></td><td class="blocked"></td> |
|||
</tr> |
|||
<tr> |
|||
<th>星期三</th> |
|||
<td class="blocked"></td><td class="blocked"></td><td class="blocked"></td><td class="blocked"></td> |
|||
<td class="blocked"></td><td class="blocked"></td><td class="blocked"></td><td class="blocked"></td> |
|||
<td class="blocked"></td><td class="blocked"></td><td class="blocked"></td><td class="blocked"></td> |
|||
<td class="blocked"></td><td class="blocked"></td><td class="blocked"></td><td class="blocked"></td> |
|||
<td class="blocked"></td><td class="blocked"></td><td class="blocked"></td><td class="blocked"></td> |
|||
<td class="blocked"></td><td class="blocked"></td><td class="blocked"></td><td class="blocked"></td> |
|||
</tr> |
|||
<tr> |
|||
<th>星期四</th> |
|||
<td class="blocked"></td><td class="blocked"></td><td class="blocked"></td><td class="blocked"></td> |
|||
<td class="blocked"></td><td class="blocked"></td><td class="blocked"></td><td class="blocked"></td> |
|||
<td class="blocked"></td><td class="blocked"></td><td class="blocked"></td><td class="blocked"></td> |
|||
<td class="blocked"></td><td class="blocked"></td><td class="blocked"></td><td class="blocked"></td> |
|||
<td class="blocked"></td><td class="blocked"></td><td class="blocked"></td><td class="blocked"></td> |
|||
<td class="blocked"></td><td class="blocked"></td><td class="blocked"></td><td class="blocked"></td> |
|||
</tr> |
|||
<tr> |
|||
<th>星期五</th> |
|||
<td class="blocked"></td><td class="blocked"></td><td class="blocked"></td><td class="blocked"></td> |
|||
<td class="blocked"></td><td class="blocked"></td><td class="blocked"></td><td class="blocked"></td> |
|||
<td class="blocked"></td><td class="blocked"></td><td class="blocked"></td><td class="blocked"></td> |
|||
<td class="blocked"></td><td class="blocked"></td><td class="blocked"></td><td class="blocked"></td> |
|||
<td class="blocked"></td><td class="blocked"></td><td class="blocked"></td><td class="blocked"></td> |
|||
<td class="blocked"></td><td class="blocked"></td><td class="blocked"></td><td class="blocked"></td> |
|||
</tr> |
|||
<tr> |
|||
<th>星期六</th> |
|||
<td class="blocked"></td><td class="blocked"></td><td class="blocked"></td><td class="blocked"></td> |
|||
<td class="blocked"></td><td class="blocked"></td><td class="blocked"></td><td class="blocked"></td> |
|||
<td class="blocked"></td><td class="blocked"></td><td class="blocked"></td><td class="blocked"></td> |
|||
<td class="blocked"></td><td class="blocked"></td><td class="blocked"></td><td class="blocked"></td> |
|||
<td class="blocked"></td><td class="blocked"></td><td class="blocked"></td><td class="blocked"></td> |
|||
<td class="blocked"></td><td class="blocked"></td><td class="blocked"></td><td class="blocked"></td> |
|||
</tr> |
|||
<tr> |
|||
<th>星期日</th> |
|||
<!-- 24 cells for each hour --> |
|||
<td class="blocked"></td><td class="blocked"></td><td class="blocked"></td><td class="blocked"></td> |
|||
<td class="blocked"></td><td class="blocked"></td><td class="blocked"></td><td class="blocked"></td> |
|||
<td class="blocked"></td><td class="blocked"></td><td class="blocked"></td><td class="blocked"></td> |
|||
<td class="blocked"></td><td class="blocked"></td><td class="blocked"></td><td class="blocked"></td> |
|||
<td class="blocked"></td><td class="blocked"></td><td class="blocked"></td><td class="blocked"></td> |
|||
<td class="blocked"></td><td class="blocked"></td><td class="blocked"></td><td class="blocked"></td> |
|||
</tr> |
|||
</tbody> |
|||
</table> |
|||
<div class="mt-3"> |
|||
<div class="d-inline-block mr-3"> |
|||
<div class="d-inline-block align-middle" style="width: 20px; height: 20px; background-color: white; border: 1px solid black;"></div> |
|||
<span class="align-middle">允许</span> |
|||
</div> |
|||
<div class="d-inline-block"> |
|||
<div class="d-inline-block align-middle" style="width: 20px; height: 20px; background-color: blue;"></div> |
|||
<span class="align-middle">阻止</span> |
|||
</div> |
|||
</div> |
|||
</div> |
|||
<script> |
|||
document.addEventListener('DOMContentLoaded', () => { |
|||
const cells = document.querySelectorAll('.schedule-table tbody td'); |
|||
cells.forEach(cell => { |
|||
cell.addEventListener('click', () => { |
|||
if (cell.classList.contains('blocked')) { |
|||
cell.classList.remove('blocked'); |
|||
cell.classList.add('allowed'); |
|||
} else { |
|||
cell.classList.remove('allowed'); |
|||
cell.classList.add('blocked'); |
|||
} |
|||
}); |
|||
}); |
|||
}); |
|||
</script> |
|||
</body> |
|||
</html> |
@ -0,0 +1,286 @@ |
|||
{% extends 'base.html' %} |
|||
|
|||
{% block title %}ZFBOX{% endblock %} |
|||
|
|||
{% block style %} |
|||
.btn-blue { |
|||
background-color: #007bff; |
|||
color: white; |
|||
} |
|||
.btn-blue:hover { |
|||
background-color: #0056b3; |
|||
} |
|||
|
|||
.table-container { |
|||
min-height: 300px; /* 设置最小高度,可以根据需要调整 */ |
|||
} |
|||
/* 缩小表格行高 */ |
|||
.table-sm th, |
|||
.table-sm td { |
|||
padding: 0.2rem; /* 调整这里的值来改变行高 */ |
|||
} |
|||
.pagination { |
|||
justify-content: flex-end; /* 右对齐 */ |
|||
} |
|||
|
|||
.section-title { |
|||
position: relative; |
|||
margin: 20px 0; |
|||
} |
|||
.section-title hr { |
|||
margin: 0; |
|||
border-color: #000; /* You can change the color of the line if needed */ |
|||
} |
|||
{% endblock %} |
|||
|
|||
{% block content %} |
|||
<div class="container d-flex flex-column" > |
|||
<!-- 模态框区域 --> |
|||
<!-- 配置IP模态框--> |
|||
<div class="modal fade" id="ipConfigModal" tabindex="-1" aria-labelledby="ipConfigModalLabel" aria-hidden="true"> |
|||
<div class="modal-dialog"> |
|||
<div class="modal-content"> |
|||
<div class="modal-header"> |
|||
<h5 class="modal-title" id="ipConfigModalLabel">IP地址配置</h5> |
|||
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button> |
|||
</div> |
|||
<div class="modal-body"> |
|||
<!-- Tabs for Wired and Wireless IP --> |
|||
<ul class="nav nav-tabs" id="ipTab" role="tablist"> |
|||
<li class="nav-item" role="presentation"> |
|||
<button class="nav-link active" id="wired-tab" data-bs-toggle="tab" data-bs-target="#wired" type="button" role="tab" aria-controls="wired" aria-selected="true">有线IP</button> |
|||
</li> |
|||
<li class="nav-item" role="presentation"> |
|||
<button class="nav-link" id="wireless-tab" data-bs-toggle="tab" data-bs-target="#wireless" type="button" role="tab" aria-controls="wireless" aria-selected="false">无线IP</button> |
|||
</li> |
|||
</ul> |
|||
<!-- Tab content --> |
|||
<div class="tab-content mt-3" id="ipTabContent"> |
|||
<!-- Wired IP Configuration --> |
|||
<div class="tab-pane fade show active" id="wired" role="tabpanel" aria-labelledby="wired-tab"> |
|||
<div class="mb-3"> |
|||
<div class="row"> |
|||
<div class="col-6"> |
|||
<div class="form-check"> |
|||
<input class="form-check-input" type="radio" name="ip_lan" |
|||
id="dhcp_lan" checked onclick="handleRadioClick_lan(event)"> |
|||
<label class="form-check-label" for="dhcp_lan">自动获取</label> |
|||
</div> |
|||
</div> |
|||
<div class="col-6"> |
|||
<div class="form-check"> |
|||
<input class="form-check-input" type="radio" name="ip_lan" |
|||
id="static_lan" onclick="handleRadioClick_lan(event)"> |
|||
<label class="form-check-label" for="static_lan">静态IP</label> |
|||
</div> |
|||
</div> |
|||
</div> |
|||
</div> |
|||
<div class="mb-3"> |
|||
<label for="wiredIpAddress" class="form-label">有线IP地址</label> |
|||
<input type="text" class="form-control" id="wiredIpAddress" placeholder="例如: 192.168.1.2"> |
|||
</div> |
|||
<div class="mb-3"> |
|||
<label for="wiredSubnetMask" class="form-label">子网掩码</label> |
|||
<input type="text" class="form-control" id="wiredSubnetMask" placeholder="例如: 255.255.255.0"> |
|||
</div> |
|||
<div class="mb-3"> |
|||
<label for="wiredGateway" class="form-label">网关</label> |
|||
<input type="text" class="form-control" id="wiredGateway" placeholder="例如: 192.168.1.1"> |
|||
</div> |
|||
<div> |
|||
<label for="wirelessGateway" class="form-label">DNS</label> |
|||
<input type="text" class="form-control" id="wiredDNS" placeholder="例如: 114.114.114.114"> |
|||
</div> |
|||
</div> |
|||
<!-- Wireless IP Configuration --> |
|||
<div class="tab-pane fade" id="wireless" role="tabpanel" aria-labelledby="wireless-tab"> |
|||
<div class="mb-2"> |
|||
<label for="wirelessNetwork" class="form-label">选择无线网络</label> |
|||
<select class="form-select" id="wirelessNetwork"> |
|||
<!-- 数据动态填充 --> |
|||
</select> |
|||
</div> |
|||
<div class="mb-4"> |
|||
<div class="row justify-content-center align-items-center"> |
|||
<div class="col-2"><label for="wirelessSubnetMask" class="form-label">密码:</label></div> |
|||
<div class="col-8"><input type="password" class="form-control" id="wifi_passwd"></div> |
|||
<div class="col-2"><button type="button" class="btn btn-primary" id="connectWifi">连接</button></div> |
|||
</div> |
|||
</div> |
|||
<div class="mb-2"> |
|||
<div class="row"> |
|||
<div class="col-6"> |
|||
<div class="form-check"> |
|||
<input class="form-check-input" type="radio" name="ip_wifi" |
|||
id="dhcp_wifi" checked onclick="handleRadioClick_wifi(event)"> |
|||
<label class="form-check-label" for="dhcp_wifi">自动获取</label> |
|||
</div> |
|||
</div> |
|||
<div class="col-6"> |
|||
<div class="form-check"> |
|||
<input class="form-check-input" type="radio" name="ip_wifi" |
|||
id="static_wifi" onclick="handleRadioClick_wifi(event)"> |
|||
<label class="form-check-label" for="static_wifi">静态IP</label> |
|||
</div> |
|||
</div> |
|||
</div> |
|||
</div> |
|||
<div class="mb-2"> |
|||
<label for="wirelessIpAddress" class="form-label">无线IP地址</label> |
|||
<input type="text" class="form-control" id="wirelessIpAddress" placeholder="例如: 192.168.1.3"> |
|||
</div> |
|||
<div class="mb-2"> |
|||
<label for="wirelessSubnetMask" class="form-label">子网掩码</label> |
|||
<input type="text" class="form-control" id="wirelessSubnetMask" placeholder="例如: 255.255.255.0"> |
|||
</div> |
|||
<div class="mb-2"> |
|||
<label for="wirelessGateway" class="form-label">网关</label> |
|||
<input type="text" class="form-control" id="wirelessGateway" placeholder="例如: 192.168.1.1"> |
|||
</div> |
|||
<div> |
|||
<label for="wirelessGateway" class="form-label">DNS</label> |
|||
<input type="text" class="form-control" id="wirelessDNS" placeholder="例如: 114.114.114.114"> |
|||
</div> |
|||
</div> |
|||
</div> |
|||
</div> |
|||
<div class="modal-footer"> |
|||
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">关闭</button> |
|||
<button type="button" class="btn btn-primary" id="saveIPConfig">保存设置</button> |
|||
</div> |
|||
</div> |
|||
</div> |
|||
</div> |
|||
<!-- 修改服务器IP模态框--> |
|||
<div class="modal fade" id="ServerIPModal" tabindex="-1" aria-labelledby="ServerIPModal" aria-hidden="true"> |
|||
<div class="modal-dialog"> |
|||
<div class="modal-content"> |
|||
<div class="modal-header"> |
|||
<h5 class="modal-title">服务器IP地址配置</h5> |
|||
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button> |
|||
</div> |
|||
<div class="modal-body"> |
|||
<div class="mb-3"> |
|||
<label for="serviceIP_model" class="form-label">服务器IP</label> |
|||
<input type="text" class="form-control" id="serviceIP_model" placeholder="例如: 127.0.0.1"> |
|||
</div> |
|||
<div class="mb-3"> |
|||
<label for="servicePort_model" class="form-label">端口号</label> |
|||
<input type="text" class="form-control" id="servicePort_model" placeholder="例如: 8085"> |
|||
</div> |
|||
</div> |
|||
<div class="modal-footer"> |
|||
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">关闭</button> |
|||
<button type="button" class="btn btn-primary" id="saveServerIP">保存设置</button> |
|||
</div> |
|||
</div> |
|||
</div> |
|||
</div> |
|||
<!-- 新增区域模态框--> |
|||
<div class="modal fade" id="addAreaModal" tabindex="-1" aria-labelledby="AreaModal" aria-hidden="true"> |
|||
<div class="modal-dialog"> |
|||
<div class="modal-content"> |
|||
<div class="modal-header"> |
|||
<h5 class="modal-title" id="area_modal_title_id">新增区域</h5> |
|||
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button> |
|||
</div> |
|||
<div class="modal-body"> |
|||
<div class="mb-3"> |
|||
<label for="area_name" class="form-label">区域名称</label> |
|||
<input type="text" class="form-control" id="area_name"> |
|||
</div> |
|||
</div> |
|||
<div class="modal-footer"> |
|||
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">关闭</button> |
|||
<button type="button" class="btn btn-primary" id="addArea">保存设置</button> |
|||
</div> |
|||
</div> |
|||
</div> |
|||
</div> |
|||
<!-- 修改区域模态框--> |
|||
<div class="modal fade" id="modifyAreaModal" tabindex="-1" aria-labelledby="AreaModal" aria-hidden="true"> |
|||
<div class="modal-dialog"> |
|||
<div class="modal-content"> |
|||
<div class="modal-header"> |
|||
<h5 class="modal-title">修改区域</h5> |
|||
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button> |
|||
</div> |
|||
<div class="modal-body"> |
|||
<div class="mb-3"> |
|||
<label for="area_name" class="form-label">区域名称</label> |
|||
<input type="text" class="form-control" id="area_name_modif"> |
|||
</div> |
|||
</div> |
|||
<div class="modal-footer"> |
|||
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">关闭</button> |
|||
<button type="button" class="btn btn-primary" id="modifArea">保存设置</button> |
|||
</div> |
|||
</div> |
|||
</div> |
|||
</div> |
|||
<!-- 系统信息区域 --> |
|||
<div class="container mt-4"> |
|||
<div class="row justify-content-center align-items-center"> |
|||
<div class="col-md-3 text-end"><label class="col-form-label form-label">系统版本号:</label></div> |
|||
<div class="col-md-9"><p class="form-control-plaintext" id="system_version">1.0.0.1</p></div> |
|||
</div> |
|||
<div class="row justify-content-center align-items-center"> |
|||
<div class="col-md-3 text-end"><label class="col-form-label form-label">升级包:</label></div> |
|||
<div class="col-md-6"><input type="file" class="form-control" id="upgrade-system"></div> |
|||
<div class="col-md-3"><button class="btn btn-blue" id="upsystem">升级</button></div> |
|||
</div> |
|||
<div class="row justify-content-center align-items-center"> |
|||
<div class="col-md-3 text-end"><label class="col-form-label form-label">设备ID:</label></div> |
|||
<div class="col-md-9"><p class="form-control-plaintext" id="dev_ID">1.0.0.1</p></div> |
|||
</div> |
|||
<div class="row justify-content-center align-items-center"> |
|||
<div class="col-md-3 text-end"><label class="col-form-label form-label">设备IP:</label></div> |
|||
<div class="col-md-6"><p class="form-control-plaintext" id="dev_IP"> |
|||
有线--192.168.3.45 WIFI--192.168.3.45 5G--192.168.3.45</p></div> |
|||
<div class="col-md-3"><button class="btn btn-blue" id="showIPConfig">配置</button></div> |
|||
</div> |
|||
<div class="row justify-content-center align-items-center"> |
|||
<div class="col-md-3 text-end"><label class="col-form-label form-label">服务器IP:</label></div> |
|||
<div class="col-md-3"><input type="text" class="form-control" id="service_ip"></div> |
|||
<div class="col-md"><label class="col-form-label form-label">端口号:</label></div> |
|||
<div class="col-md"><input type="text" class="form-control" id="service_port"></div> |
|||
<div class="col-md-3"><button class="btn btn-blue" id="showServerIP">修改</button></div> |
|||
</div> |
|||
</div> |
|||
<!-- 区域管理区域 --> |
|||
<div class="section-title"> |
|||
<hr> |
|||
</div> |
|||
<div class="mb-3"> |
|||
<button id="addAreaButton" type="button" class="btn btn-primary"> |
|||
新增区域 |
|||
</button> |
|||
</div> |
|||
<div class="table-container"> |
|||
<table class="table"> |
|||
<thead class="table-light"> |
|||
<tr> |
|||
<th scope="col" style="width: 20%;">ID</th> |
|||
<th scope="col" style="width: 50%;">区域名称</th> |
|||
<th scope="col" style="width: 30%;">操作</th> |
|||
</tr> |
|||
</thead> |
|||
<tbody id="table-body-area" class="table-group-divider"> |
|||
<!-- 表格数据动态填充 --> |
|||
</tbody> |
|||
</table> |
|||
<nav> |
|||
<ul id="pagination-area" class="pagination"> |
|||
<!-- 分页控件将动态生成 --> |
|||
</ul> |
|||
</nav> |
|||
</div> |
|||
|
|||
</div> |
|||
{% endblock %} |
|||
|
|||
{% block script %} |
|||
<script src="{{ url_for('main.static', filename='scripts/jquery-3.2.1.slim.min.js') }}"></script> |
|||
<script src="{{ url_for('main.static', filename='scripts/system_manager.js') }}"></script> |
|||
{% endblock %} |
@ -0,0 +1,48 @@ |
|||
{% extends 'base.html' %} |
|||
|
|||
{% block title %}ZFBOX{% endblock %} |
|||
|
|||
{% block style %} |
|||
.note { |
|||
color: red; |
|||
font-size: 0.9rem; |
|||
} |
|||
.btn-blue { |
|||
background-color: #007bff; |
|||
color: white; |
|||
} |
|||
.btn-blue:hover { |
|||
background-color: #0056b3; |
|||
} |
|||
{% endblock %} |
|||
|
|||
{% block content %} |
|||
<div class="container d-flex flex-column" > |
|||
<div class="row justify-content-center align-items-center mb-2"> |
|||
<div class="col-md-2 text-end"><label class="col-form-label form-label">用户名:</label></div> |
|||
<div class="col-md-7"><p class="form-control-plaintext" id="system_version">zfadmin</p></div> |
|||
</div> |
|||
<div class="row justify-content-center align-items-center mb-2"> |
|||
<div class="col-md-2 text-end"><label class="col-form-label form-label">原密码:</label></div> |
|||
<div class="col-md-7"><input type="password" class="form-control" id="source_passwd"></div> |
|||
</div> |
|||
<div class="row justify-content-center align-items-center mb-2"> |
|||
<div class="col-md-2 text-end"><label class="col-form-label form-label">新密码:</label></div> |
|||
<div class="col-md-7"><input type="password" class="form-control" id="new_passwd"></div> |
|||
</div> |
|||
<div class="row justify-content-center align-items-center mb-2"> |
|||
<div class="col-md-2 text-end"><label class="col-form-label form-label">确认密码:</label></div> |
|||
<div class="col-md-7"><input type="password" class="form-control" id="again_passwd"></div> |
|||
</div> |
|||
<div class="row justify-content-center align-items-center mb-2"> |
|||
<div class="col-md-6 text-end"></div> |
|||
<div class="col-md-3"><button class="btn btn-blue w-100" id="changePasswd">修改密码</button></div> |
|||
</div> |
|||
|
|||
|
|||
</div> |
|||
{% endblock %} |
|||
|
|||
{% block script %} |
|||
<script src="{{ url_for('main.static', filename='scripts/user_manager.js') }}"></script> |
|||
{% endblock %} |
@ -1,367 +0,0 @@ |
|||
<!DOCTYPE html> |
|||
<html> |
|||
<head> |
|||
<title>实时预览</title> |
|||
<meta http-equiv="X-UA-Compatible" content="IE=edge"/> |
|||
<meta http-equiv="content-type" content="text/html; charset=utf-8"/> |
|||
<link href="resources/css/axure_rp_page.css" type="text/css" rel="stylesheet"/> |
|||
<link href="data/styles.css" type="text/css" rel="stylesheet"/> |
|||
<link href="files/实时预览/styles.css" type="text/css" rel="stylesheet"/> |
|||
<script src="resources/scripts/jquery-3.2.1.min.js"></script> |
|||
<script src="resources/scripts/axure/axQuery.js"></script> |
|||
<script src="resources/scripts/axure/globals.js"></script> |
|||
<script src="resources/scripts/axutils.js"></script> |
|||
<script src="resources/scripts/axure/annotation.js"></script> |
|||
<script src="resources/scripts/axure/axQuery.std.js"></script> |
|||
<script src="resources/scripts/axure/doc.js"></script> |
|||
<script src="resources/scripts/messagecenter.js"></script> |
|||
<script src="resources/scripts/axure/events.js"></script> |
|||
<script src="resources/scripts/axure/recording.js"></script> |
|||
<script src="resources/scripts/axure/action.js"></script> |
|||
<script src="resources/scripts/axure/expr.js"></script> |
|||
<script src="resources/scripts/axure/geometry.js"></script> |
|||
<script src="resources/scripts/axure/flyout.js"></script> |
|||
<script src="resources/scripts/axure/model.js"></script> |
|||
<script src="resources/scripts/axure/repeater.js"></script> |
|||
<script src="resources/scripts/axure/sto.js"></script> |
|||
<script src="resources/scripts/axure/utils.temp.js"></script> |
|||
<script src="resources/scripts/axure/variables.js"></script> |
|||
<script src="resources/scripts/axure/drag.js"></script> |
|||
<script src="resources/scripts/axure/move.js"></script> |
|||
<script src="resources/scripts/axure/visibility.js"></script> |
|||
<script src="resources/scripts/axure/style.js"></script> |
|||
<script src="resources/scripts/axure/adaptive.js"></script> |
|||
<script src="resources/scripts/axure/tree.js"></script> |
|||
<script src="resources/scripts/axure/init.temp.js"></script> |
|||
<script src="resources/scripts/axure/legacy.js"></script> |
|||
<script src="resources/scripts/axure/viewer.js"></script> |
|||
<script src="resources/scripts/axure/math.js"></script> |
|||
<script src="resources/scripts/axure/jquery.nicescroll.min.js"></script> |
|||
<script src="data/document.js"></script> |
|||
<script src="files/实时预览/data.js"></script> |
|||
<script type="text/javascript"> |
|||
$axure.utils.getTransparentGifPath = function() { return 'resources/images/transparent.gif'; }; |
|||
$axure.utils.getOtherPath = function() { return 'resources/Other.html'; }; |
|||
$axure.utils.getReloadPath = function() { return 'resources/reload.html'; }; |
|||
</script> |
|||
</head> |
|||
<body> |
|||
<div id="base" class=""> |
|||
|
|||
<!-- Unnamed (web框架一) --> |
|||
|
|||
<!-- Unnamed (Rectangle) --> |
|||
<div id="u16" class="ax_default flow_shape"> |
|||
<div id="u16_div" class=""></div> |
|||
<div id="u16_text" class="text " style="display:none; visibility: hidden"> |
|||
<p></p> |
|||
</div> |
|||
</div> |
|||
|
|||
<!-- Unnamed (Rectangle) --> |
|||
<div id="u17" class="ax_default flow_shape"> |
|||
<div id="u17_div" class=""></div> |
|||
<div id="u17_text" class="text " style="display:none; visibility: hidden"> |
|||
<p></p> |
|||
</div> |
|||
</div> |
|||
|
|||
<!-- Unnamed (Rectangle) --> |
|||
<div id="u18" class="ax_default heading_1"> |
|||
<div id="u18_div" class=""></div> |
|||
<div id="u18_text" class="text "> |
|||
<p><span>智凡BOX</span></p> |
|||
</div> |
|||
</div> |
|||
|
|||
<!-- Unnamed (Rectangle) --> |
|||
<div id="u19" class="ax_default heading_3"> |
|||
<div id="u19_div" class=""></div> |
|||
<div id="u19_text" class="text "> |
|||
<p><span>@2024 ZFKJ All Rights Reserved </span></p> |
|||
</div> |
|||
</div> |
|||
|
|||
<!-- Unnamed (Menu) --> |
|||
<div id="u20" class="ax_default"> |
|||
<img id="u20_menu" class="img " src="images/实时预览/u20_menu.png" alt="u20_menu"/> |
|||
|
|||
<!-- Unnamed (Table) --> |
|||
<div id="u21" class="ax_default"> |
|||
|
|||
<!-- Unnamed (Menu Item) --> |
|||
<div id="u22" class="ax_default menu_item"> |
|||
<img id="u22_img" class="img " src="images/实时预览/u22.png"/> |
|||
<div id="u22_text" class="text "> |
|||
<p><span>实时预览</span></p> |
|||
</div> |
|||
</div> |
|||
|
|||
<!-- Unnamed (Menu Item) --> |
|||
<div id="u23" class="ax_default menu_item"> |
|||
<img id="u23_img" class="img " src="images/实时预览/u22.png"/> |
|||
<div id="u23_text" class="text "> |
|||
<p><span>通道管理</span></p> |
|||
</div> |
|||
</div> |
|||
|
|||
<!-- Unnamed (Menu Item) --> |
|||
<div id="u24" class="ax_default menu_item"> |
|||
<img id="u24_img" class="img " src="images/实时预览/u22.png"/> |
|||
<div id="u24_text" class="text "> |
|||
<p><span>算法管理</span></p> |
|||
</div> |
|||
</div> |
|||
|
|||
<!-- Unnamed (Menu Item) --> |
|||
<div id="u25" class="ax_default menu_item"> |
|||
<img id="u25_img" class="img " src="images/实时预览/u22.png"/> |
|||
<div id="u25_text" class="text "> |
|||
<p><span>系统管理</span></p> |
|||
</div> |
|||
</div> |
|||
|
|||
<!-- Unnamed (Menu Item) --> |
|||
<div id="u26" class="ax_default menu_item"> |
|||
<img id="u26_img" class="img " src="images/实时预览/u26.png"/> |
|||
<div id="u26_text" class="text "> |
|||
<p><span>用户管理</span></p> |
|||
</div> |
|||
</div> |
|||
</div> |
|||
</div> |
|||
|
|||
<!-- Unnamed (Shape) --> |
|||
<div id="u27" class="ax_default icon"> |
|||
<img id="u27_img" class="img " src="images/登录/u4.svg"/> |
|||
<div id="u27_text" class="text " style="display:none; visibility: hidden"> |
|||
<p></p> |
|||
</div> |
|||
</div> |
|||
|
|||
<!-- Unnamed (Rectangle) --> |
|||
<div id="u28" class="ax_default heading_3"> |
|||
<div id="u28_div" class=""></div> |
|||
<div id="u28_text" class="text "> |
|||
<p><span>张三</span></p> |
|||
</div> |
|||
</div> |
|||
|
|||
<!-- Unnamed (Rectangle) --> |
|||
<div id="u29" class="ax_default primary_button"> |
|||
<div id="u29_div" class=""></div> |
|||
<div id="u29_text" class="text "> |
|||
<p><span>退出</span></p> |
|||
</div> |
|||
</div> |
|||
<div id="u15" style="display:none; visibility:hidden;"></div> |
|||
|
|||
<!-- Unnamed (Rectangle) --> |
|||
<div id="u30" class="ax_default primary_button"> |
|||
<div id="u30_div" class=""></div> |
|||
<div id="u30_text" class="text "> |
|||
<p><span>实时预览</span></p> |
|||
</div> |
|||
</div> |
|||
|
|||
<!-- Unnamed (Rectangle) --> |
|||
<div id="u31" class="ax_default flow_shape"> |
|||
<div id="u31_div" class=""></div> |
|||
<div id="u31_text" class="text " style="display:none; visibility: hidden"> |
|||
<p></p> |
|||
</div> |
|||
</div> |
|||
|
|||
<script src="/resources/scripts/aiortc-client-new.js"> |
|||
console.log('当指定了src属性时,浏览器会加载并执行该文件中的脚本,而忽略标签内部的任何内容,所以不会执行'); |
|||
</script> |
|||
|
|||
<!-- Unnamed (Image) --> |
|||
<div id="u32" class="ax_default image"> |
|||
<img id="u32_video" src="" alt="Video Stream"> |
|||
</div> |
|||
<!-- Unnamed (Image) --> |
|||
<div id="u33" class="ax_default image"> |
|||
<img id="u33_video" src="" alt="Video Stream"> |
|||
</div> |
|||
|
|||
|
|||
<!-- Unnamed (Image) --> |
|||
<div id="u34" class="ax_default image"> |
|||
<!-- <video id="u34_video" autoplay="true" playsinline="true"></video>--> |
|||
<img id="u34_video" src="" alt="Video Stream"> |
|||
</div> |
|||
|
|||
<!-- Unnamed (Image) --> |
|||
<div id="u35" class="ax_default image"> |
|||
<!-- <video id="u35_video" autoplay="true" playsinline="true"></video>--> |
|||
<img id="u35_video" src="" alt="Video Stream"> |
|||
</div> |
|||
|
|||
<!-- Unnamed (Image) --> |
|||
<div id="u36" class="ax_default image"> |
|||
<!-- <video id="u36_video" autoplay="true" playsinline="true"></video>--> |
|||
<img id="u36_video" src="" alt="Video Stream"> |
|||
</div> |
|||
|
|||
<!-- Unnamed (Image) --> |
|||
<div id="u37" class="ax_default image"> |
|||
<!-- <video id="u37_video" autoplay="true" playsinline="true"></video>--> |
|||
<img id="u37_video" src="" alt="Video Stream"> |
|||
</div> |
|||
|
|||
<!-- Unnamed (Image) --> |
|||
<div id="u38" class="ax_default image"> |
|||
<!-- <video id="u38_video" autoplay="true" playsinline="true"></video>--> |
|||
<img id="u38_video" src="" alt="Video Stream"> |
|||
</div> |
|||
|
|||
<!-- Unnamed (Image) --> |
|||
<div id="u39" class="ax_default image"> |
|||
<!-- <video id="u39_video" autoplay="true" playsinline="true"></video>--> |
|||
<img id="u39_video" src="" alt="Video Stream"> |
|||
</div> |
|||
|
|||
<!-- Unnamed (Image) --> |
|||
<div id="u40" class="ax_default image"> |
|||
<img id="u40_img" class="img " src="images/实时预览/u32.png"/> |
|||
<div id="u40_text" class="text " style="display:none; visibility: hidden"> |
|||
<p></p> |
|||
</div> |
|||
</div> |
|||
|
|||
<!-- Unnamed (Rectangle) --> |
|||
<div id="u41" class="ax_default label"> |
|||
<div id="u41_div" class=""></div> |
|||
<div id="u41_text" class="text "> |
|||
<p><span><< 1/2 >></span></p> |
|||
</div> |
|||
</div> |
|||
|
|||
<!-- Unnamed (Rectangle) --> |
|||
<div id="u42" class="ax_default button"> |
|||
<div id="u42_div" class=""></div> |
|||
<div id="u42_text" class="text "> |
|||
<p><span>一画面</span></p> |
|||
</div> |
|||
</div> |
|||
|
|||
<!-- Unnamed (Rectangle) --> |
|||
<div id="u43" class="ax_default button"> |
|||
<div id="u43_div" class=""></div> |
|||
<div id="u43_text" class="text "> |
|||
<p><span>四画面</span></p> |
|||
</div> |
|||
</div> |
|||
|
|||
<!-- Unnamed (Rectangle) --> |
|||
<div id="u44" class="ax_default button"> |
|||
<div id="u44_div" class=""></div> |
|||
<div id="u44_text" class="text "> |
|||
<p><span>九画面</span></p> |
|||
</div> |
|||
</div> |
|||
|
|||
<!-- Unnamed (Rectangle) --> |
|||
<div id="u45" class="ax_default button"> |
|||
<div id="u45_div" class=""></div> |
|||
<div id="u45_text" class="text "> |
|||
<p><span>十六<br>画面</span></p> |
|||
</div> |
|||
</div> |
|||
|
|||
<!-- Unnamed (Tree) --> |
|||
<div id="u46" class="ax_default tree_node treeroot"> |
|||
<div id="u46_children" class="u46_children"> |
|||
|
|||
<!-- Unnamed (Tree Node) --> |
|||
<div id="u47" class="ax_default tree_node treenode"> |
|||
|
|||
<!-- Unnamed (Image) --> |
|||
<div id="u48" class="ax_default image"> |
|||
<img id="u48_img" class="img " src="images/实时预览/u48_selected.png"/> |
|||
<div id="u48_text" class="text " style="display:none; visibility: hidden"> |
|||
<p></p> |
|||
</div> |
|||
</div> |
|||
<!-- Unnamed (Rectangle) --> |
|||
<div id="u49" class="" selectiongroup="u46_tree_group"> |
|||
<div id="u49_div" class=""></div> |
|||
<div id="u49_text" class="text "> |
|||
<p><span>一厂区</span></p> |
|||
</div> |
|||
</div> |
|||
<div id="u47_children" class="u47_children"> |
|||
|
|||
<!-- Unnamed (Tree Node) --> |
|||
<div id="u50" class="ax_default tree_node treenode"> |
|||
<!-- Unnamed (Rectangle) --> |
|||
<div id="u51" class="" selectiongroup="u46_tree_group"> |
|||
<div id="u51_div" class=""></div> |
|||
<div id="u51_text" class="text "> |
|||
<p><span>北门通道一</span></p> |
|||
</div> |
|||
</div> |
|||
</div> |
|||
|
|||
<!-- Unnamed (Tree Node) --> |
|||
<div id="u52" class="ax_default tree_node treenode"> |
|||
<!-- Unnamed (Rectangle) --> |
|||
<div id="u53" class="" selectiongroup="u46_tree_group"> |
|||
<div id="u53_div" class=""></div> |
|||
<div id="u53_text" class="text "> |
|||
<p><span>南门通道二</span></p> |
|||
</div> |
|||
</div> |
|||
</div> |
|||
|
|||
<!-- Unnamed (Tree Node) --> |
|||
<div id="u54" class="ax_default tree_node treenode"> |
|||
<!-- Unnamed (Rectangle) --> |
|||
<div id="u55" class="" selectiongroup="u46_tree_group"> |
|||
<div id="u55_div" class=""></div> |
|||
<div id="u55_text" class="text "> |
|||
<p><span>通道三</span></p> |
|||
</div> |
|||
</div> |
|||
</div> |
|||
</div> |
|||
</div> |
|||
|
|||
<!-- Unnamed (Tree Node) --> |
|||
<div id="u56" class="ax_default tree_node treenode"> |
|||
|
|||
<!-- Unnamed (Image) --> |
|||
<div id="u57" class="ax_default image"> |
|||
<img id="u57_img" class="img " src="images/实时预览/u48_selected.png"/> |
|||
<div id="u57_text" class="text " style="display:none; visibility: hidden"> |
|||
<p></p> |
|||
</div> |
|||
</div> |
|||
<!-- Unnamed (Rectangle) --> |
|||
<div id="u58" class="" selectiongroup="u46_tree_group"> |
|||
<div id="u58_div" class=""></div> |
|||
<div id="u58_text" class="text "> |
|||
<p><span>二区域</span></p> |
|||
</div> |
|||
</div> |
|||
<div id="u56_children" class="u56_children"> |
|||
|
|||
<!-- Unnamed (Tree Node) --> |
|||
<div id="u59" class="ax_default tree_node treenode"> |
|||
<!-- Unnamed (Rectangle) --> |
|||
<div id="u60" class="" selectiongroup="u46_tree_group"> |
|||
<div id="u60_div" class=""></div> |
|||
<div id="u60_text" class="text "> |
|||
<p><span>通道一</span></p> |
|||
</div> |
|||
</div> |
|||
</div> |
|||
</div> |
|||
</div> |
|||
</div> |
|||
</div> |
|||
</div> |
|||
<script src="resources/scripts/axure/ios.js"></script> |
|||
</body> |
|||
</html> |